2010-06-11 14 views
10

Me sorprendió mucho cuando vi esta notación. ¿Qué hace y qué tipo de noción C es?¿Qué significa "int * a = (int [2]) {0, 2};" exactamente hacer?

+0

No compila con VC++ al compilar en modo C. ¿Qué compilador has probado? – AraK

+0

Funciona en GCC, ¿quizás no está en el estándar C? – Dpp

+0

Voy a adivinar que tienes razón, que esta es otra extensión de GCC. Sin embargo, no estoy seguro de lo que gana con eso. –

Respuesta

19

Este es un compuesto literal como se define en la sección 6.5.2.5 de la norma C99.

No forma parte del lenguaje C++, por lo que no es sorprendente que los compiladores de C++ no lo compilen. (o compiladores Java o Ada para el caso)

El valor del literal compuesto es el de un objeto sin nombre inicializado por la lista de inicializadores . Si el literal compuesto ocurre fuera del cuerpo de una función, el objeto tiene una duración de almacenamiento estático; de lo contrario, tiene una duración de almacenamiento automática asociada con el bloque adjunto.

Así que no, no destruirá la pila. El compilador asigna almacenamiento para el objeto.

Los paréntesis se colocan alrededor del tipo y luego sigue una lista de inicialización; no es un molde, ya que una lista de inicializadores desnudos no tiene ningún significado en la sintaxis C99; en su lugar, es un operador de postfijo aplicado a un tipo que produce un objeto del tipo dado. No está creando { 0, 3 } y lanzándolo a una matriz, está inicializando un int[2] con los valores 0 y 3.


cuanto a por qué se usa, no veo una buena razón para ello en su sola línea, aunque podría ser que una podría ser reasignado a apuntar en algún otro arreglo, y por lo que es un camino más corto de hacer las dos primeras líneas de:

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

if (some_test) a = get_another_array(); 

he encontrado que es útil para pasar uniones temporales de funciones

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

¡Gran explicación! Buen ejemplo con la unión, es una manera bastante corta de inicializar y pasar un puntero a una función. Parece que se ve como matrices anónimas. Lástima que no está implementado en C++ – Dpp

+0

Acabo de buscar una matriz anónima en C++ y parece que algo similar se va a implementar en C++ 0x: std :: initializer_list <>, donde, para nuestro ejemplo, puede especificar std :: initializer_list como argumento en el prototipo de función y proporcionar una lista de inicializadores como {0, 2} a la función. – Dpp

-2
  • {0, 2} es la notación para una matriz que consiste en 0 y 2.
  • (int[2]) lo convierte en un array (no sé por qué).
  • int * a = lo asigna al puntero int a.
+0

Sin el molde, el compilador lo ve como un intento de asignar valores múltiples a una variable escalar. – eemz

+5

-1 No es un elenco. – Artefacto

0

(int [2]) le dice al compilador que la siguiente expresión debe enviarse a int [2]. Esto es necesario ya que {0, 2} se puede convertir a diferentes tipos, como long [2]. La conversión se produce en tiempo de compilación, no en tiempo de ejecución.

Toda la expresión crea una matriz en la memoria y establece un punto para esta matriz.

1
  1. Asigna, en la pila, espacio para [una matriz de] dos int s.
  2. Rellena [la matriz de] los dos int s con los valores 0 y 2, respectivamente.
  3. Declara una variable local del tipo int* y asigna a esa variable la dirección de [la matriz de] los dos int s.
6

Ésta es una construcción c99, llamado compuesto literal.

Desde el comité de proyecto de sección 6.5.2.5 mayo de 2005:

Una expresión de sufijo que consiste en un nombre de tipo entre paréntesis seguido de una lista cerrada de brace- inicializadores es un compuesto literal. Proporciona un objeto sin nombre cuyo valor viene dado por la lista de inicializadores.

...

Ejemplo 1 La definición ámbito de archivo

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

inicializa p para que apunte al primer elemento de un gama de dos enteros, el primero que tiene la valor dos y el segundo, cuatro. Las expresiones en este compuesto literal deben ser constantes. El objeto sin nombre tiene una duración de almacenamiento estático de .

Cuestiones relacionadas