这个编译器业务不是我的强项。。。
我想在我的嵌入式c++代码中使用<string>
模板库。
例如(sudo代码(:
#include <string>
int main() {
std::string str = std::to_string(3.87628);
}
当我试图编译这个代码时,我得到了错误:
error: 'to_string' is not a member of 'std'
我的Makefile包含以下标志:
# compile gcc flags
ASFLAGS = $(MCU) $(AS_DEFS) $(AS_INCLUDES) $(OPT) -Wall -fdata-sections -ffunction-sections
CFLAGS = $(MCU) $(C_DEFS) $(C_INCLUDES) $(OPT) -Wall -fdata-sections -ffunction-sections
# Generate dependency information
CFLAGS += -MMD -MP -MF"$(@:%.o=%.d)"
# C++ Flags
CPPFLAGS = $(CFLAGS)
CPPFLAGS +=
-fno-exceptions
-fno-rtti
C_STANDARD = -std=gnu11
CPP_STANDARD += -std=gnu++14
据我所知,包含标志-std=gnu++14
应该让我涵盖不?
std::to_string
是库的一部分,而不是语言的一部分。因此,如果-std=gnu++14
没有在库中实现,它将没有任何作用。检查头文件以查看
- 声明,并且
- 如果它依赖于正在定义的任何宏
该库与编译器是分开的,您的工具链可能使用较旧的C++库或针对嵌入式系统的精简库。你的工具链来源于哪里?它使用的是什么C++库?标题中的版权消息可能会提供线索,包括版本信息。
std::string
库在嵌入式系统中通常是不合适的,因为它依赖于非确定性的动态内存分配。
由于您的代码表明您实际上使用的是C字符串而不是std::string
,因此您可能会考虑:
#include <cstdio>
int main()
{
char str[32] ;
std::snprintf( str, sizeof(str), "%f", 3.87628 ) ;
}
嵌入式系统中存在C++是有问题的。让我们在g++ARM32 10.2.1 gcc none-eabi编译器上运行您的代码,并启用最大优化-O3 -std=c++17
:
.LC0:
.ascii "%f 00"
main:
str lr, [sp, #-4]!
adr r1, .L15
ldmia r1, {r0-r1}
sub sp, sp, #36
stm sp, {r0-r1}
ldr r3, .L15+8
add r0, sp, #8
mov r2, #328
ldr r1, .L15+12
bl std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > __gnu_cxx::__to_xstring<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, char>(int (*)(char*, unsigned int, char const*, std::__va_list), unsigned int, char const*, ...)
ldr r0, [sp, #8]
add r3, sp, #16
cmp r0, r3
ldrne r1, [sp, #16]
addne r1, r1, #1
blne _ZdlPvj
mov r0, #0
add sp, sp, #36
ldr lr, [sp], #4
bx lr
.L15:
.word 380705901
.word 1074725535
.word .LC0
.word vsnprintf
现在这一切都是胡说八道!?我忘了-O3
标志了吗,嗯,不,我没有。。。你发布的程序没有副作用。或者我们是这么想的——我们一直是cplusplus:ed。我本希望一个行为正确的编译器在-O3
下生成无代码。
所以问题显然不是如何在项目中使用CCD_;在C++2x中,你没有使用constexpr,这不是你写现代C++的方式;。问题是,一旦某个PC程序员因为某人决定允许C++而将这个完全不可接受的代码拖到你的微控制器中,如何挽救这个项目。答案如下:
步骤1:切换到C。相同的编译器ARM32 10.2.1 gcc none-eabi。
第二步:在不需要膨胀类的时候,不要把时间浪费在膨胀类上。一件简单的事情,比如将浮点常量转换为字符串,可以而且应该在预处理器中完成。任何中级C或C++程序员都应该了解字符串化宏:
#define S(x) #x #define STR(x) S(x)
第三步:测试。一个简单的测试程序,带有
-ffreestanding
和一些副作用,以确保字符串不会被优化,例如:#include <stdio.h> #define S(x) #x #define STR(x) S(x) void main (void) { char str[] = STR(3.87628); puts(str); // just to introduce a side effect }
生成的机器代码的相关部分现在是这样的:
.LC0:
.ascii "3.87628 00"
main:
str lr, [sp, #-4]!
sub sp, sp, #12
mov r3, sp
ldr r2, .L4
ldm r2, {r0, r1}
stm r3, {r0, r1}
.L4:
.word .LC0
这个代码很好。我们可以继续写申请了。