当我看到这个符号时,感到非常惊讶。它是做什么的,属于什么类型的C符号呢?
这是C99标准第6.5.2.5节中定义的复合文字。
由于它不是C++语言的一部分,因此C++编译器无法编译它(事实上,Java或Ada编译器也无法编译)。
复合文字的值是一个由初始化列表初始化的未命名对象的值。如果复合文字出现在函数体外,则对象具有静态存储期;否则,它具有与封闭块关联的自动存储期。
因此,它不会破坏堆栈。编译器为对象分配存储空间。
括号将类型括起来,然后跟随初始化列表——这不是一个转换,因为在C99语法中,裸初始化列表没有意义;相反,它是应用于类型的后缀运算符,产生给定类型的对象。你没有创建{ 0, 3 }
并将其强制转换为数组,而是使用值0和3初始化了一个int[2]
。
至于为什么要使用它,在你的单行代码中我看不出一个好的理由,尽管可能是因为a可能被重新分配到某个其他的数组,所以这是做前两行的更短的方法:
int default_a[] = { 0, 2 };
int *a = default_a;
if (some_test) a = get_another_array();
我发现它对于将临时联合传递给函数非常有用
// fills an array of unions with a value
kin_array_fill ( array, ( kin_variant_t ) { .ref = value } )
这是c99的一个构造,称为复合字面量。
来自2005年5月委员会草案第6.5.2.5节:
由括号括起来的类型名称后跟大括号括起来的初始化器列表组成的后缀表达式是复合字面量。它提供了一个未命名对象,其值由初始化器列表给出。
...
示例1 文件范围定义
int *p = (int []){2, 4};
int
数组分配空间。int
数组的值分别设置为 0
和 2
。int*
的本地变量,并将该变量赋值为两个 int
数组的地址。(int[2]) 告诉编译器以下表达式应该被转换为 int[2]。这是必需的,因为 {0, 2} 可以被转换为不同的类型,比如 long[2]。强制转换发生在编译时 - 不是运行时。
整个表达式在内存中创建一个数组,并将 a 指向此数组。
{0, 2}
是一个由0和2组成的数组的表示法。(int[2])
将其转换为一个数组(不知道为什么)。int * a =
将其赋值给整型指针a。