2012-04-12 14 views
6

He mirado en éstos y que no responde a mi pregunta:gcc se queja: objeto de tamaño variable no puede ser inicializado

variable-sized object may not be initialized

C compile error: "Variable-sized object may not be initialized"

Error: Variable-sized object may not be initialized. But why?


soy tratando de escribir algún código bastante portable c:

int main() 
{ 
    const int foo=13; 
    int bar[foo]={0}; 
    return 0; 
} 


me sale un error al compilar variable-sized object may not be initialized como c código utilizando:

  • gcc 4.3.4
  • brazo-linux-gcc 4.4.5 gnueabi-

Y si lo compilo como c en VS2008 me sale un poco diferente error C2057: expected constant expression


entiendo que aquí, el compilador c código no está reconociendo const int foo=13; ser verdaderamente constante; por ejemplo, podríamos tener

void a(int fool) 
{  
    const int foo=fool; 
    int bar[foo]={0}; 
} 


también darse cuenta de que unlike the gcc compilers, el compilador VS2008 no tiene concepto de C99 variable-length arrays. Y ese MS aparentemente no ha mencionado ningún soporte futuro.


Y, sin embargo, cpp compilación de código, ya sea con gcc o MS compiladores es totalmente diferente/más inteligente?!


Y también lo que no entiendo con respecto a la gccc compilador de código es:


(NB: en este último caso, MSc compilación de código falla; consistentemente como con int bar[foo]={0};)

+0

En mi TDM-GCC 4.6.1 el último ejemplo no ** compila ** (de nuevo con "objeto de tamaño variable no puede ser inicializado"). Tampoco había oído nunca que los VLAs se inicializaran con una lista de inicializadores, ¿es esto correcto C? Investigándolo ... – Anthales

+0

Para la parte de su pregunta sobre los compiladores de MS, esta no es la única característica que falta, simplemente no son compatibles con C99. Desde el año pasado, incluso hay una versión más nueva del estándar, C11, por lo que ahora carecen de 2 versiones principales. –

+0

@ [anthales] (http://stackoverflow.com/users/1250595/anthales), gracias. hmm .. – violet313

Respuesta

10

C99 §6.7.8 Inicialización dice esto:

El tipo de la entidad a ser inicializado será una matriz de tamaño desconocido o un tipo de objeto que es no una variable tipo de matriz de longitud

Así que su inicialización no es válido C.

La única manera para que type a[size] a no sea un VLA es para size a ser una expresión constante número entero (§6.7.5.2). Lo que tiene allí no es una expresión constante entera, por lo que tiene un VLA:

Si el tamaño no está presente, el tipo de matriz es incompleto. Si el tamaño es * en lugar de ser una expresión, el tipo de matriz es un tipo de matriz de longitud variable de tamaño no especificado, , que solo se puede usar en declaraciones con alcance de prototipo de función, tales matrices son , no obstante, tipos completos. Si el tamaño es una expresión constante entera y el tipo de elemento tiene un tamaño constante conocido, el tipo de matriz no es un tipo de matriz de longitud variable; de lo contrario, el tipo de matriz es un tipo de matriz de longitud variable.

Parte §6.6/6 Las expresiones constantes los define como:

Un entero expresión constante tendrá tipo entero y sólo tendrá operandos que son constantes enteras, constantes de enumeración, las constantes de caracteres, sizeof expresiones cuyos resultados son constantes enteras y constantes flotantes que son los operandos inmediatos de moldes . Los operadores de transmisión en una expresión constante de enteros solo deben convertir tipos aritméticos a tipos enteros, excepto como parte de un operando al tamaño del operador .

+0

Ok. Entonces 'foo + 1' no puede ser una expresión constante entera, ya que en tiempo de compilación no es posible conocer el valor de' foo', incluso si está declarado como 'const'. Entonces es un error en mi gcc. – violet313

+1

Curiosamente, 'clang' admite' foo + 1' como extensión: http://clang.llvm.org/docs/UsersManual.html#c_ext – Mat

+0

Todavía me molesta por qué en http://ideone.com/Br6cC , array 'bar' se trata como un VLA. ya que se puede determinar en tiempo de compilación que 'foo' es de hecho una constante entera.De hecho, me incliné a descubrir qué tipo de código ensamblador realmente se genera para algo como 'const int foo = 13;' – violet313

1

En realidad, para mi gcc (versión 4.4.4), el último ejemplo

int main() 
{ 
    const int foo=13; 
    int bar[foo+1]={0}; //wtF? 
    return 0; 
} 

también no se compila, como cabría esperar. Es posible que desee volver a verificar su cadena de herramientas (para verificar que no volvió a vincular un '.o' existente en alguna parte), y vuelva a intentarlo.

Si ve que realmente funciona, aquí está mi salida gcc -v, quizás pueda detectar una diferencia en la configuración y eso podría arrojar algo de luz.

Using built-in specs. 
Target: i686-redhat-linux 
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-bootstrap --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-languages=c,c++,objc,obj-c++,java,fortran,ada --enable-java-awt=gtk --disable-dssi --enable-plugin --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-1.5.0.0/jre --enable-libgcj-multifile --enable-java-maintainer-mode --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --disable-libjava-multilib --with-ppl --with-cloog --with-tune=generic --with-arch=i686 --build=i686-redhat-linux 
Thread model: posix 
gcc version 4.4.4 20100630 (Red Hat 4.4.4-10) (GCC) 
+0

bueno, me sale [esto] (http://pastebin.com/5TKnuStM) ~ no estoy seguro de qué debería estar buscando tbh -puede que parezca que estoy cayendo en falta de otro * Debian squeeze stable * effect – violet313

+0

Todavía no entiendo por qué 'cpp' funciona, pero' c' no lo hace. Quiero decir que puedo ver que el compilador 'cpp' tiene toda la información necesaria para no arrojar un error. pero ¿hay algún estándar c para específicamente * que no se comporte de la misma manera? – violet313

+0

@ violet313, mi publicación fue que 'cpp' _does not_ work. Aparentemente está usando un compilador diferente, o incluso una copia configurada diferente de 'cpp'. El que está utilizando no funciona correctamente si le permitió compilar; es un error en ese compilador (y si te preocupa la portabilidad, no deberías usar tal compilación incluso si tu compilador lo permitió). –

0

Como Matt ya se ha citado la norma, const calificativo aplicado a una variable entera no cuenta como una expresión constante entera. Podríamos preguntarnos por qué?¡Parece tan inocente como una constante entera!

Esto puede sea porque const no son absolutamente consts. Puede alterar sus valores a través de punteros y todo lo que un compilador podría hacer, si es que atrapa dicha asignación, lanzará una advertencia pero realmente no puede evitar que se altere el valor const.

PS: no confían en la línea compiladores como ideone.com etc. He aquí una tonta runtime error se lanza para un programa en C muy simple.

+0

ha. justo pero originalmente logré el problema y luego compilé las pruebas en mi * debian squeeze * - y luego descubrí que el compilador ideone hizo lo mismo, lo que me pareció conveniente y pareció hacer la pregunta más relevante – violet313

Cuestiones relacionadas