“Int size = 10;” produce un’espressione costante?

Il seguente codice compila sotto gcc 4.8 e Clang 3.2:

int main() { int size = 10; int arr[size]; } 

8.3.4 / 1 dello standard C ++ afferma che la dimensione di un array deve essere un’espressione costante integrale, che non sembra essere la dimensione. Si tratta di un bug in entrambi i compilatori o mi manca qualcosa?

L’ultimo CTP VC ++ rifiuta il codice con questo interessante messaggio:

 error C2466: cannot allocate an array of constant size 0 

La parte interessante è come sembra pensare che la size sia zero. Ma almeno rifiuta il codice. Non dovrebbero fare lo stesso anche Gcc e Clang?

Questo è array di lunghezza variabile o VLA che è una caratteristica C99 ma gcc e clang lo supportano come un’estensione in C ++ mentre Visual Studio no . Quindi Visual Studio è conforms allo standard in questo caso ed è tecnicamente corretto. Per non dire che le estensioni sono cattive, il kernel di Linux dipende da molte estensioni gcc , quindi possono essere utili in determinati contesti.

Se aggiungi il flag -pedantic sia gcc che clang ti -pedantic di questo, per esempio gcc dice ( -pedantic dal vivo ):

 warning: ISO C++ forbids variable length array 'arr' [-Wvla] int arr[size]; ^ 

L’uso del -pedantic-errors renderà questo un errore. Puoi leggere ulteriori informazioni sulle estensioni di questi documenti. Standard di lingua supportati da GCC e clangs Compatibilità linguistica .

Aggiornare

La bozza dello standard C ++ copre ciò che è un’espressione costante integrata nella sezione 5.19 Espressioni costanti paragrafo 3 e dice:

Un’espressione di costante integrale è un’espressione di tipo di enumerazione integrale o senza ambito, convertita implicitamente in un valore di preregolazione, in cui l’espressione convertita è un’espressione di costante di nucleo. […]

Non è intuitivamente ovvio dal leggere ciò che sono tutte le possibilità, ma le Linee guida di codifica di Boost per le espressioni costanti integrali fanno un ottimo lavoro.

In questo caso poiché si sta inizializzando la size con un valore letterale utilizzando const sarebbe sufficiente renderlo un’espressione costante integrale (si veda [expr.const] p2.9.1 ) e anche riportare il codice allo standard C ++ :

 const int size = 10; 

usare constexpr potrebbe funzionare anche:

 constexpr int size = 10; 

Probabilmente sarebbe utile leggere Differenza tra constexpr e const .

Per riferimento, la sezione equivalente 8.3.4 paragrafo 1 nella bozza di standard C99 sarebbe la sezione 6.7.5.2 Dichiaratori di array paragrafo 4 che dice ( enfasi mia ):

Se la dimensione non è presente, il tipo di matrice è un tipo incompleto. Se la dimensione è * invece di essere un’espressione, il tipo di matrice è un tipo di array di lunghezza variabile di dimensioni non specificate, che può essere utilizzato solo in dichiarazioni con ambito prototipo di funzione; 124) tali matrici sono tuttavia 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 .