__typeof__ 中的“(void)0”有什么用?

mug*_*896 5 c

我目前正在查看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)

tst*_*isl 5

PTR当它恰好是指向数组或函数的指针或指向限定类型​​的指针时,它将有所帮助。逗号运算符 in((void)0,x)将强制 L 值转换。它基本上意味着将对象转换为值。对于数组,它将数组转换为指向其第一个元素的指针。转换为函数指针的函数。volatile限定类型会失去,const或 等限定符_Atomic

左值转换几乎在所有情况下都会发生,除了地址运算符&sizeof_Alignofgcc 的__typeof__typeof在即将推出的 C23 中)。

正如评论中所说,强制转换 tovoid用于消除有关 未使用值的警告0

  1. 指向数组的指针

看:

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*

  1. 函数指针。

对于函数指针,情况类似于指向数组的指针。

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)

编译得很好。

  1. 指向限定类型​​的指针。

认为:

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