C++无需调用函数获取本地静态错误信息的替代方案(TouchGFX模拟器)
我需要在不同文件的C++代码中,于setError函数调用下方添加如下形式的错误信息:
{ setError(1); // 1将被唯一常量(枚举值)替换 #ifdef SIMULATOR ADD_INFO_FOR_ERROR(1, "some explanation for error 1"); #endif }
该信息仅在定义SIMULATOR宏时生效,无需调用对应本地函数,就能在main()中获取这些信息并导出为表格。
原本我通过GCC的段属性实现该需求,定义如下宏:
#define ADD_INFO_FOR_ERROR(INTEGERVALUE, CONSTANTTEXT) \ static const struct { \ int index; \ const char *text; \ } entry_##INTEGERVALUE __attribute__((section(".my_table_section"), used)) = {INTEGERVALUE, CONSTANTTEXT};
但该方案在TouchGFX模拟器中无法正常获取信息(嵌入式生产系统可正常运行)。我使用GCC编译器,请问是否有可行的替代方案或工具?
方案1:C++全局对象自动注册
借助标准C++全局对象的构造特性实现注册逻辑,不依赖编译器段属性:
首先定义全局注册表和注册器结构:
#include <vector> #include <utility> #ifdef SIMULATOR // 全局错误信息注册表 static std::vector<std::pair<int, const char*>> error_info_registry; // 注册器对象,构造时自动将错误信息加入注册表 struct ErrorInfoRegistrar { ErrorInfoRegistrar(int code, const char* msg) { error_info_registry.emplace_back(code, msg); } }; // 替换原宏,用静态注册器对象实现自动注册 #define ADD_INFO_FOR_ERROR(CODE, MSG) \ static ErrorInfoRegistrar error_reg_##CODE(CODE, MSG); #else // 非SIMULATOR环境下宏为空 #define ADD_INFO_FOR_ERROR(CODE, MSG) #endif
使用时直接在setError下方插入ADD_INFO_FOR_ERROR(1, "some explanation for error 1")即可。程序启动后,所有注册的错误信息都会存入error_info_registry,在main()中遍历该容器就能导出表格。
优势:完全符合C++标准,跨平台兼容性强,TouchGFX模拟器环境可正常工作。
方案2:GCC构造函数属性实现C风格注册
利用GCC的__attribute__((constructor))扩展,让注册函数在main执行前自动运行:
#ifdef SIMULATOR #include <stdlib.h> // 错误信息存储表格 #define MAX_ERROR_ENTRIES 100 static struct { int code; const char* msg; } error_table[MAX_ERROR_ENTRIES]; static int error_count = 0; // 注册错误信息的函数 static void register_error(int code, const char* msg) { if (error_count < MAX_ERROR_ENTRIES) { error_table[error_count++] = {code, msg}; } } // 宏定义:生成带constructor属性的静态注册函数 #define ADD_INFO_FOR_ERROR(CODE, MSG) \ static void reg_error_##CODE(void) __attribute__((constructor)); \ static void reg_error_##CODE(void) { \ register_error(CODE, MSG); \ } #else #define ADD_INFO_FOR_ERROR(CODE, MSG) #endif
每个ADD_INFO_FOR_ERROR会生成一个自动执行的注册函数,将错误信息写入全局表格,main()中直接读取error_table和error_count即可。
注意:__attribute__((constructor))是GCC扩展,TouchGFX模拟器基于桌面GCC编译,兼容性有保障。
方案3:预处理器扫描生成静态注册表
通过脚本扫描源代码中的宏调用,编译前生成包含所有错误信息的静态文件:
- 先定义用于标记的空宏:
#ifdef SIMULATOR #define ADD_INFO_FOR_ERROR(CODE, MSG) ERROR_ENTRY(CODE, MSG) #else #define ADD_INFO_FOR_ERROR(CODE, MSG) #endif
- 编写脚本(如Python)遍历所有
.cpp文件,提取ERROR_ENTRY的参数,自动生成error_info_auto_gen.cpp:
#include "error_info.h" // 自动生成的错误信息数组 const ErrorEntry error_entries[] = { {1, "some explanation for error 1"}, {2, "some explanation for error 2"}, // 所有扫描到的错误条目 }; const size_t error_entry_count = sizeof(error_entries)/sizeof(error_entries[0]);
- 在
main()中直接使用生成的error_entries数组导出表格。
优势:运行时无额外初始化逻辑,所有错误信息编译时固定,适合对启动流程有严格要求的场景。
内容的提问来源于stack exchange,提问作者Ernie Mur

