为什么我不能在arm-none-eabi-g++编译器中使用std::string



这个编译器业务不是我的强项。。。

我想在我的嵌入式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  "%f00"
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.8762800"
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

这个代码很好。我们可以继续写申请了。

相关内容

  • 没有找到相关文章

最新更新