2012-04-12 12 views
6

Ho guardato questi e non risponde alla mia domanda:gcc si lamenta: oggetto variabile di dimensioni non può essere inizializzato

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?


Sono cercando di scrivere un codice c abbastanza portatile:

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


ottengo un errore di variable-sized object may not be initialized quando si compila come c codice utilizzando:

  • gcc 4.3.4
  • braccio-linux-gcc 4.4.5 gnueabi-

E se lo compilo come c in VS2008 ottengo leggermente diversa error C2057: expected constant expression


comprendo che qui, il c codice compilatore non riconosce const int foo=13; essere veramente costante; per esempio potremmo avere

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


mi rendo anche conto che unlike the gcc compilers, il compilatore VS2008 non ha il concetto di C99 variable-length arrays. E che MS non ha menzionato alcun supporto futuro.


Eppure, cpp codice di compilazione sia con gcc o MS compilatori è del tutto diverso/intelligente?!


E anche quello che non capisco per quanto riguarda la gccc codice compilatore è:


(NB: in quest'ultimo caso, MSc codice di compilazione fallisce; costantemente come con int bar[foo]={0};)

+0

Sul mio TDM-GCC 4.6.1 l'ultimo esempio ** non ** compila (di nuovo con "oggetto di dimensioni variabili non può essere inizializzato"). Inoltre non ho mai sentito parlare di VLA inizializzati da una lista di inizializzatori, è corretto C? Guardando dentro .. – Anthales

+0

Per la parte della tua domanda sui compilatori MS questa non è l'unica caratteristica che manca, semplicemente non supporta C99. Dall'anno scorso c'è anche una versione più recente dello standard, C11, quindi ora mancano 2 versioni principali dietro. –

+0

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

risposta

10

C99 §6.7.8 inizializzazione dice questo:

Il tipo di entità da inizializzare deve essere un array di dimensione sconosciuta o un tipo di oggetto che è non una variabile tipo di array di lunghezza.

Così il vostro inizializzazione è valido C.

L'unico modo per type a[size]-non essere un VLA è per size di essere un costante intera espressione (§6.7.5.2). Quello che hai non è un'espressione costante intera, quindi hai un VLA:

Se la dimensione non è presente, il tipo di matrice è un tipo incompleto. Se la dimensione è * anziché essere un'espressione, il tipo di matrice è un tipo di matrice di lunghezza variabile di dimensione non specificata, che può essere utilizzato solo in dichiarazioni con ambito prototipo di funzione tali matrici sono uguali a tipi completi. Se la dimensione è un'espressione costante intera e il tipo di elemento ha una dimensione costante nota, il tipo di matrice non è un tipo di matrice di lunghezza variabile; in caso contrario, il tipo di matrice è un tipo di matrice di lunghezza variabile.

Parte §6.6/6 espressioni costanti li definisce:

Un numero intero espressione costante deve avere tipo intero e avrà solo operandi che sono costanti intere, le costanti di enumerazione, costanti carattere, sizeof espressioni i cui risultati sono costanti integer e costanti mobili che sono gli operandi immediati di . Gli operatori di cast in un'espressione costante intera devono convertire solo i tipi aritmetici nei tipi interi solo da , tranne che come parte di un operando per le dimensioni dell'operatore .

+0

Ok. Quindi 'foo + 1' non può essere un'espressione di costante intera, dal momento che al momento della compilazione non è possibile conoscere il valore di' foo' anche se è dichiarato come 'const'. Quindi è un bug nel mio gcc. – violet313

+1

È interessante notare che 'clang' supporta' foo + 1' come estensione: http://clang.llvm.org/docs/UsersManual.html#c_ext – Mat

+0

Mi sta ancora lamentando perché in http://ideone.com/Br6cC , array 'bar' viene trattato come un VLA. dato che è possibile determinare al momento della compilazione che 'pippo' sia effettivamente una costante intera.infatti sono incline a scoprire quale tipo di codice assembly viene effettivamente generato per qualcosa come 'const int foo = 13;' – violet313

1

In realtà, per il mio gcc (versione 4.4.4), il tuo ultimo esempio

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

anche non compilare, proprio come ci si aspetterebbe. Potresti voler ricontrollare la tua toolchain (per verificare di non aver ricollegato un ".o" esistente da qualche parte) e riprovare.

Se si trova che funziona davvero, ecco il mio output gcc -v, forse è possibile rilevare una differenza nella configurazione e che potrebbe dare un po 'di luce.

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

beh io ottengo [questo] (http://pastebin.com/5TKnuStM) ~ non sono proprio sicuro di cosa dovrei cercare tbh -looks come se potessi cadere in fallo di un'altra * debian squeeze effetto stabile * – violet313

+0

Non riesco ancora a capire perché 'cpp' funziona, ma' c' no. Voglio dire che posso vedere che il compilatore 'cpp' ha tutte le informazioni necessarie per non generare un errore. ma c'è qualche c-standard per specificamente * che non si comporta allo stesso modo? – violet313

+0

@ violet313, Il mio post è stato che 'cpp' _does_ non funziona. Apparentemente stai usando un compilatore diverso, o anche solo una copia configurata diversa di 'cpp'. Quello che stai usando non funziona correttamente se ti permette di compilare; è un bug in quel compilatore (e se ti interessa la portabilità, non dovresti usare un simile costrutto anche se il compilatore lo permetteva). –

0

Come Matt ha già citato standard, const qualificazione applicata a una variabile intera non conta come costante intera espressione. Potremmo chiederci perché?Sembra innocente come una costante intera!

Questo può essere perché const non sono assolutamente consts. Potresti alterare i loro valori attraverso i puntatori e tutto ciò che un compilatore potrebbe fare, se non riesce a cogliere un simile incarico, è un avvertimento ma non può davvero impedirti di modificare il valore const.

PS: non si fidano dei compilatori in linea come ideone.com ecc Ecco uno sciocco runtime error getta per un programma molto semplice C.

+0

ha. equo punto ma inizialmente ho colpito il problema e poi ho compilato i test sul mio * debian squeeze * - e poi ho scoperto che il compilatore ideone ha fatto la stessa cosa - che sembrava sia conveniente e sembrava rendere la domanda più pertinente – violet313

Problemi correlati