[英]Why can I not use std::string with the arm-none-eabi-g++ compiler?
這個編譯器業務不是我的強項...
我想在我的嵌入式 c++ 代碼中使用<string>
模板庫。
例如(須藤代碼):
#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
如果沒有在庫中實現就沒有效果。 檢查 header 文件看是否
您提供的代碼也是胡說八道。 它應該是:
std::string str = std::to_string(3.87628);
但這不會解決你的問題。
該庫與編譯器分開,您的工具鏈可能使用的是較舊的 C++ 庫或針對嵌入式系統的精簡庫。 您從哪里獲得工具鏈以及它使用的是什么 C++ 庫? header 中的版權信息可能會提供一個線索——包括版本信息。
std::string
庫在嵌入式系統中通常不合適,因為除其他問題外,它依賴於非確定性動態 memory 分配。
由於您的代碼表明您實際上使用的是 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\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
標志,呵呵,不,我沒有……您發布的程序沒有副作用。 或者我們認為 - 我們一直是 cplusplus:ed。 我本來希望一個行為正確的編譯器在-O3
下不生成任何代碼。
所以問題顯然不是如何在項目中使用std::string
,答案也不是“在 C++2x 中,你沒有使用 constexpr 這不是你編寫現代 C++ blahblah 的方式”。 問題是,一旦某些 PC 程序員將這個完全不可接受的代碼拖到您的微控制器中,只是因為有人決定允許 C++,如何挽救該項目。 答案如下:
第一步:切換到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
這段代碼很好。 我們可以繼續編寫我們的應用程序。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.