C++ 在嵌入式系统中的存在是有问题的。让我们在启用了最大优化的 g++ ARM32 10.2.1 gcc none-eabi 编译器上运行您的代码-O3 -std=c++17
:
.LC0:
.ascii "%f\000"
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
flag,呵呵,不,我没有……你发布的程序没有副作用。或者我们认为 - 我们一直是 cplusplus:ed。我本来期望一个行为正确的编译器在-O3
.
所以问题显然不是如何std::string
在项目中使用,答案也不是“在 C++2x 中你没有使用 constexpr,这不是你编写现代 C++ blahblah 的方式”。问题是,一旦某些 PC 程序员将这个完全不可接受的代码拖到您的微控制器中,只是因为有人决定允许 C++,如何挽救该项目。答案如下:
第 1 步:切换到 C。相同的编译器 ARM32 10.2.1 gcc none-eabi。
第 2 步:当不需要它们时,不要将时间浪费在臃肿的课程上。一个简单的事情,例如将浮点常量转换为字符串,可以而且应该在预处理器中完成。任何中级 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\000"
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
这段代码很好。我们可以继续编写我们的应用程序。