首页 > 解决方案 > 用大括号括起来的结构是什么意思?

问题描述

最近,我正在跟踪一些源代码。当我看到以下宏时,我卡住了。

#define tmp(x)                                          \
((void) ((struct {                                     \
     _Static_assert(sizeof(x) <= 16, "Err"); \
     int dum;                                        \
 }){1})

该宏用于检查 x 的大小是否小于 16。

我有两个关于这个宏的问题。

首先,以下格式含义中的struct是什么,这种风格有没有关键字?

(struct {                       
     .......                                      
 }){1};

其次,为什么要把 assert 放在 struct 里面?为什么不直接调用_Static_assertmain 呢?

标签: cstruct

解决方案


这种“带括号的声明和初始化”被称为复合文字。这个语法特性首先出现在 C99 中。它的基本语法是:

( type ) { initializer-list }

因此,如果我们省略_Static_cast, is (struct { int dum; }){1},那么您在这里所拥有的,它声明了一个未命名的结构并创建了一个包含该结构的复合文字dum==1。类型转换为void简单地丢弃值,避免可能的“未使用值”警告。

其次,为什么要把 assert 放在 struct 里面?为什么不直接调用_Static_assertmain 呢?

如果您注意到,这会扩展为不以分号结尾的内容;。(我认为缺少右括号)是您的复制粘贴错误。)因此它可以用作子表达式,例如

#define tmp(x)                               \
((void) ((struct {                           \
     _Static_assert(sizeof(x) <= 16, "Err"); \
     int dum;                                \
 }){1}))

#include <stdio.h>
int main()
{
    const int x=324;
    const double y=(tmp(x), 23.342);
    printf("%g\n", y);
}

不知道为什么会想要这个,但至少这个宏的作者在某些情况下需要它时可以使用它。


推荐阅读