全局常量结构体数组初始化:将字符串放入指定段(无中间变量)
实现全局结构体数组初始化中字符串存入指定段的SPECIAL_STR宏
问题回顾
给定如下C语言结构体:
struct entry { int id; const char *name; };
需要全局初始化该结构体数组entries并将其放入.special段,同时要求数组中所有字符串字面量(如"foo"、"bar")也存入.special段,禁止使用中间变量和#pragma rodata-name。原有宏仅能在函数内使用,无法满足全局初始化需求。
解决方案
使用以下宏定义即可实现全局场景下的字符串段指定:
#define SPECIAL_STR(X) \ (&(static const char __attribute__((__section__(".special"))) __str_##X[] = X)[0])
使用示例
const static struct entry entries[] __attribute__((__section__(".special"))) = { {0, SPECIAL_STR("foo"), }, {1, SPECIAL_STR("bar"), }, {}, };
原理说明
宏的结构解析:
__str_##X:通过预处理器的令牌拼接(##)为每个字符串生成唯一的静态变量名,避免重名冲突。static const char __attribute__((__section__(".special"))) __str_##X[] = X:定义一个静态字符数组,显式指定其存储段为.special,并用传入的字符串字面量X初始化。&[...]:直接取数组首元素的地址,作为结构体中const char *name的初始化值,这是合法的编译期常量表达式,符合全局初始化器的要求。
原宏不可用的原因:
原有宏使用了GCC的语句表达式(({...}))语法,该语法仅允许在函数体内使用,而全局变量的初始化器必须是编译期可求值的常量表达式,因此无法适配全局场景。
注意事项
- 若同一字符串字面量被多次使用,宏会生成多个独立的静态字符数组。如果需要合并相同字符串以节省空间,可以为变量添加
__attribute__((__weak__))属性,但这会引入弱符号的相关规则,需根据实际需求调整。
内容的提问来源于stack exchange,提问作者rralf
相关产品推荐
相关产品推荐

