关于C语言从泛型选择返回复合字面量的安全性及宏展开结果的技术问询
关于C语言从泛型选择返回复合字面量的安全性及宏展开结果的技术问询
嘿,咱们来一步步拆解你的问题,先把宏展开的事儿说清楚,再聊返回复合字面量地址的安全性问题。
第一个问题:PRINT(&a)的宏展开结果
当你调用PRINT(&a)时,预处理阶段会把宏完全展开:
- 第一个
_Generic匹配到int*类型,直接返回print_int这个函数指针 - 第二个
_Generic同样匹配int*分支,返回&(int){*&a}这个表达式
所以最终展开后的代码就是:
print_int(&(int){*&a});
编译阶段编译器会自动把*&a优化成a,实际等价于print_int(&(int){a}),但宏展开的原始文本就是带*&a的版本。你也可以这么理解:泛型选择返回的就是复合字面量的地址,这个地址直接作为print_int的参数传递。
第二个问题:泛型选择返回复合字面量地址的安全性
这种用法是完全符合C标准且安全的,咱们掰碎了说:
- 复合字面量的生命周期规则:如果它出现在函数的块作用域内(没有加
static修饰),它的生命周期和当前块的自动变量完全一致,直到所在块执行结束才会被销毁 - 你的宏展开后,复合字面量是在
main函数的块里创建的,而print_int的调用也处于同一个块中。当print_int执行时,这个复合字面量还处于它的生命周期内,所以它的地址是有效的,函数内部访问*p不会出现悬空指针这类未定义行为 - 泛型选择只是负责选择对应的分支表达式,并不会改变复合字面量的作用域和生命周期,所以C标准完全保证这种用法的安全性
内容来源于stack exchange
相关产品推荐
相关产品推荐

