如何用同类型值初始化复合字面量?实现通用MAKE_CLITERAL宏
解决方案:实现通用的复合字面量生成宏
你的问题核心在于两种宏实现各自的局限性:
- 第一种宏
((typeof(T)) {T})对结构体变量失效,因为C标准不允许直接将结构体对象作为复合字面量初始化列表的单个元素; - 第二种宏是赋值表达式,结果为右值,无法进行取地址操作。
可行的宏实现
使用以下宏可以同时支持标量字面量、结构体变量等任意类型的值,且生成的复合字面量支持取地址:
#define MAKE_CLITERAL(T) ((typeof(T)){ *&(T) })
验证示例
typedef struct S { int i; char c; } S; #define MAKE_CLITERAL(T) ((typeof(T)){ *&(T) }) int main() { // 标量类型测试 int x = MAKE_CLITERAL(10); int* px = &MAKE_CLITERAL(20); // 支持取地址操作 // 结构体类型测试 S s = {.i = 500, .c = 'a'}; S s2 = MAKE_CLITERAL(s); // 编译通过,正确复制结构体值 S* ps = &MAKE_CLITERAL(s); // 支持取复合字面量的地址 return 0; }
原理说明
*&(T)的作用是将输入表达式T转换为左值:
- 若
T是变量(如结构体实例s),&(T)获取其地址,解引用后得到原变量的左值; - 若
T是字面量(如10),&(T)会生成指向临时值的指针,解引用后得到对应类型的左值。
C标准允许用左值表达式作为复合字面量的初始化器,因此该宏可以适配任意类型的输入,且生成的复合字面量是左值,支持取地址操作。
内容的提问来源于stack exchange,提问作者Abdulmalek Almkainzi
相关产品推荐
相关产品推荐

