简体   繁体   English

什么是“int * a =(int [2]){0,2};”究竟做什么?

[英]What does “int *a = (int[2]){0, 2};” exactly do?

I was very surprised when I saw this notation. 当我看到这种符号时,我感到非常惊讶。 What does it do and what kind of C notion is it? 它是做什么的,它是什么样的C概念?

This is a compound literal as defined in section 6.5.2.5 of the C99 standard. 这是C99标准第6.5.2.5节中定义的复合文字。

It's not part of the C++ language, so it's not surprising that C++ compilers don't compile it. 它不是C ++语言的一部分,因此C ++编译器不编译它就不足为奇了。 (or Java or Ada compilers for that matter) (或Java或Ada编译器)

The value of the compound literal is that of an unnamed object initialized by the initializer list. 复合文字的值是初始化列表初始化的未命名对象的值。 If the compound literal occurs outside the body of a function, the object has static storage duration; 如果复合文字出现在函数体外,则该对象具有静态存储持续时间; otherwise, it has automatic storage duration associated with the enclosing block. 否则,它具有与封闭块相关的自动存储持续时间。

So no, it won't destroy the stack. 所以不,它不会破坏堆栈。 The compiler allocates storage for the object. 编译器为对象分配存储空间。

Parenthesis are put around the type and it is then followed by an initializer list - it's not a cast, as a bare initialiser list has no meaning in C99 syntax; 括号是围绕类型放置的,然后是初始化列表 - 它不是强制转换,因为裸初始化列表在C99语法中没有意义; instead, it is a postfix operator applied to a type which yields an object of the given type. 相反,它是一个后缀运算符,应用于产生给定类型的对象的类型。 You are not creating { 0, 3 } and casting it to an array, you're initialising an int[2] with the values 0 and 3. 您没有创建{ 0, 3 }并将其强制转换为数组,而是使用值0和3初始化int[2]


As to why it's used, I can't see a good reason for it in your single line, although it might be that a could be reassigned to point at some other array, and so it's a shorter way of doing the first two lines of: 至于为什么使用它,我在单行中看不出它的好理由,尽管它可能被重新分配以指向其他一些数组,所以它是一个较短的方式来做前两行:

int default_a[] = { 0, 2 };
int *a = default_a;

if (some_test) a = get_another_array();

I've found it useful for passing temporary unions to functions 我发现将临时联合传递给函数很有用

// fills an array of unions with a value
kin_array_fill ( array, ( kin_variant_t ) { .ref = value } )

This is a c99 construct, called a compound literal . 这是一个c99构造,称为复合文字

From the May 2005 committee draft section 6.5.2.5: 从2005年5月的委员会草案第6.5.2.5节:

A postfix expression that consists of a parenthesized type name followed by a brace- enclosed list of initializers is a compound literal. 后缀表达式由带括号的类型名称后跟括号括起的初始值列表组成,是一个复合文字。 It provides an unnamed object whose value is given by the initializer list. 它提供了一个未命名的对象,其值由初始化列表给出。

... ...

EXAMPLE 1 The file scope definition 示例1文件范围定义

int *p = (int []){2, 4}; 

initializes p to point to the first element of an array of two ints, the first having the value two and the second, four. 初始化p指向两个整数数组的第一个元素,第一个元素的值为2,第二个元素的值为4。 The expressions in this compound literal are required to be constant. 此复合文字中的表达式必须是常量。 The unnamed object has static storage duration. 未命名的对象具有静态存储持续时间。

  1. Allocates, on the stack, space for [an array of] two int s. 在堆栈上为[两个int的数组]分配空间。
  2. Populates [the array of] the two int s with the values 0 and 2 , respectively. 使用值02分别填充两个int的[数组]。
  3. Declares a local variable of type int* and assigns to that variable the address of [the array of] the two int s. 声明一个int*类型的局部变量,并为该变量分配两个int的[数组]的地址。

(int[2]) tells the compiler that the following expression should be casted to int[2]. (int [2])告诉编译器下面的表达式应该转换为int [2]。 This is required since {0, 2} can be casted to different types, like long[2]. 这是必需的,因为{0,2}可以被转换为不同类型,例如long [2]。 Cast occurs at compile time - not runtime. 转换发生在编译时 - 而不是运行时。

The entire expression creates an array in memory and sets a to point to this array. 整个表达式在内存中创建一个数组,并将a设置为指向此数组。

  • {0, 2} is the notation for an array consisting of 0 and 2. {0, 2}是由0和2组成的数组的表示法。
  • (int[2]) casts it to an array (don't know why) . (int[2]) 将它转换为数组(不知道为什么)
  • int * a = assigns it to the int pointer a. int * a =将它赋给int指针a。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM