我目前正在ubuntulinux中查看stdatomic.h
头文件。(void)0
和逗号在__typeof__ ((void)0, *__atomic_store_ptr)
中有什么用?
这不需要什么吗?
#define atomic_store_explicit(PTR, VAL, MO) \
__extension__ \
({ \
__auto_type __atomic_store_ptr = (PTR); \
__typeof__ ((void)0, *__atomic_store_ptr) __atomic_store_tmp = (VAL); \
__atomic_store (__atomic_store_ptr, &__atomic_store_tmp, (MO)); \
})
1条答案
按热度按时间cwtwac6a1#
当
PTR
恰好是一个数组或函数的指针,或者是一个限定类型的指针时,它会有帮助。((void)0,x)
中的逗号操作符将强制进行L值转换。它基本上意味着将一个对象转换为一个值。在数组的情况下,它将数组转换为指向其第一个元素的指针。转换为函数指针的函数。限定类型失去了volatile
、const
或_Atomic
等限定符。除了地址运算符
&
、sizeof
、_Alignof
和gcc的__typeof__
(typeof
将在即将到来的C23中出现)之外,几乎所有情况下都会发生左值转换。正如评论中所说的,强制转换为
void
用于消除有关0
未使用值的警告。1.数组指针
参见:
如果未强制进行L值转换,则宏将展开为:
也就是
以及
其变为:
因为解引用
int(*)[3]
产生int[3]
。由于使用指针初始化数组,这将导致编译失败。
使用这个技巧,上面的代码将变成:
因为
int[3]
通过进行L值转换而被变换为int*
。1.函数指针。
对于函数指针,情况类似于指向数组的指针。
扩展至:
以及
因为取消引用
(void(*)(void)
会生成函数类型void(void)
。由于C中不允许使用初始化函数,因此编译失败。利用这个技巧,上面的声明变成:
它编译良好。
1.指向限定类型的指针。
假设:
现在:
以及:
现在该值变为
volatile
,导致性能下降等细微问题。使用左值转换时,__atomic_store_tmp
的类型变为非限定int
。