2010-12-31 15 views
6

Digamos que escribo char c[99] = {'Stack Overflow'}; en C o C++. Compila bien pero ¿es esto válido? Por válido, quise decir no invocar ningún tipo de comportamiento indefinido o no especificado.¿Es esta una declaración válida de C?

Nuevamente si escribo char c[99] = 'Stack Overflow'; gcc se queja de la constante multicharacter que es obvia, pero en el apartado anterior cuando estoy entre corchetes el compilador está contento. ¿Por que es esto entonces?

También observo que puts(c); después de la primera instrucción dará salida 'w' precisamente el último carácter de una cadena general en el lugar de Stack Overflow. ¿Porque?

¿Alguien podría explicar estos comportamientos por separado?

+3

Compilarlo y descubrirlo. – Falmarri

+5

Él ya dijo que lo compiló ... – indiv

+22

@Falmarri: Creo que ganaste el premio RTFQ. Dijo "compila bien" y también describe la salida, obviamente lo probó. Pero las pruebas no le dicen si es portátil o está bien definido por el estándar. –

Respuesta

14

Ambos son solo un literal, por lo que c[0] se establece en el literal y c[1] ... c[98] se llena con cero (carácter NUL).

Creo que el valor realmente se rellena en c[0] depende de la implementación, pero al menos debe compilarse en cualquier compilador compatible.

EDIT: verificados contra la norma, en C++ 0x al menos:

Un literal multicaracter tiene tipo int y el valor definido por la implementación.

Y en C99 (usando the draft, la causa es libre):

El valor de una constante de carácter entero que contiene más de un carácter (por ejemplo, 'ab'), o que contiene un carácter o secuencia de escape que no se correlaciona con un carácter de ejecución de un solo byte, está definido por la implementación.

+1

+1 Bienvenido al mundo de los caracteres multi-caracteres literal –

+0

Hm pero ¿por qué el enunciado con corchetes pasa la comprobación sintáctica del compilador? – Quixotic

+1

@Philando: Porque es un " Inicializador compuesto "que se usa para inicializar una matriz" Eso es perfectamente legal. No hay ninguna regla que los inicializadores compuestos tengan que tener más de un elemento, de hecho cosas como 'int a [10] = {0};' son muy comunes. –

1

Código de kernel de Windows acordado: ve mucha memoria de etiquetado. Y en realidad está implementado por plataforma. Sin embargo, utilizan ULONG para etiquetar la memoria, y siempre es un literal de 4 caracteres en orden inverso: ULONG tagMemory = 'kscf';

La interpretación es específica de la plataforma, pero una secuencia de caracteres.

Cuestiones relacionadas