我目前正在查看stdatomic.hubuntu linux中的头文件。和 中的逗号
有什么用?
这不需要什么吗?(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)); \
})
Run Code Online (Sandbox Code Playgroud)
PTR当它恰好是指向数组或函数的指针或指向限定类型的指针时,它将有所帮助。逗号运算符 in((void)0,x)将强制 L 值转换。它基本上意味着将对象转换为值。对于数组,它将数组转换为指向其第一个元素的指针。转换为函数指针的函数。volatile限定类型会失去,const或 等限定符_Atomic。
左值转换几乎在所有情况下都会发生,除了地址运算符&、sizeof和_Alignofgcc 的__typeof__(typeof在即将推出的 C23 中)。
正如评论中所说,强制转换 tovoid用于消除有关 未使用值的警告0。
看:
int arr[3];
int (*ptr)[3];
atomic_store_explicit(ptr, &arr, XXX);
Run Code Online (Sandbox Code Playgroud)
如果没有强制进行 L 值转换,则宏将扩展为:
__auto_type __atomic_store_ptr = (ptr);
Run Code Online (Sandbox Code Playgroud)
这是
int (*__atomic_store_ptr)(ptr);
Run Code Online (Sandbox Code Playgroud)
和
__typeof__ (*__atomic_store_ptr) __atomic_store_tmp = (VAL);
Run Code Online (Sandbox Code Playgroud)
变成:
int __atomic_store_tmp[3] = arr;
Run Code Online (Sandbox Code Playgroud)
因为解除引用int(*)[3]会产生int[3].
由于用指针初始化数组,会导致编译失败。
通过这个技巧,上面的代码将变成:
int *__atomic_store_tmp = arr;
Run Code Online (Sandbox Code Playgroud)
因为通过进行左值转换int[3]来转换为。int*
对于函数指针,情况类似于指向数组的指针。
void foo(void);
void (*ptr)(void);
atomic_store_explicit(ptr, foo, X);
Run Code Online (Sandbox Code Playgroud)
扩展到:
...
__auto_type __atomic_store_ptr = (PTR);
==>
void (*__atomic_store_ptr)(void) = ptr;
Run Code Online (Sandbox Code Playgroud)
和
__typeof__ (*__atomic_store_ptr) __atomic_store_tmp = (VAL);
==>
void __atomic_store_tmp(void) = foo;
Run Code Online (Sandbox Code Playgroud)
因为解引用(void(*)(void)会产生一个函数类型 void(void)。由于 C 中不允许初始化函数,编译失败。
通过这个技巧,上面的声明变成:
void (*__atomic_store_tmp)(void) = foo;
Run Code Online (Sandbox Code Playgroud)
编译得很好。
认为:
volatile int *ptr;
atomic_store_explicit(ptr, 42, XXX);
Run Code Online (Sandbox Code Playgroud)
现在:
__auto_type __atomic_store_ptr = (ptr);
==>
volatile int *__atomic_store_ptr = ptr;
Run Code Online (Sandbox Code Playgroud)
和:
__typeof__ (*__atomic_store_ptr) __atomic_store_tmp = (val);
==>
volatile int __atomic_store_tmp = val;
Run Code Online (Sandbox Code Playgroud)
现在,该值会volatile导致一些微妙的问题,例如性能较差。通过左值转换, 的类型__atomic_store_tmp变得不合格int。