2015-08-25 19 views
9

Avevo l'impressione che le dichiarazioni di matrice di dimensioni variabili non fossero possibili in C89. Ma, quando si compila con clang -ansi Sono in grado di eseguire il codice seguente:Utilizzo di sizeof() nelle dichiarazioni di array in C89

double array[] = { 0.0, 1.0, 2.0, 3.0, 4.0 }; 
double other_array[sizeof(array)] = { 0.0 }; 

Che cosa sta succedendo qui? Non è considerata una dichiarazione di matrice di dimensioni variabili?

+0

whaoppps, editied –

+1

vi sono campi di variabili dimensioni in C89, quindi non può essere considerato un dichiarazione dell'array di dimensioni variabili. . –

risposta

5

Questo perché risultato di sizeof operatore è costante espressione, quindi non si qualifica per VLA, proprio come la seguente dichiarazione:

int other_array[5]; 

non può essere matrice di lunghezza variabile sia. Da C11 (N1570) §6.6/p6 espressioni costanti (sottolineatura mia andando avanti):

Un costante intera espressione117) avranno tipo integer e si avere solo operandi che sono costanti intere , le costanti di enumerazione, costanti carattere, sizeof espressioni cui risultati sono interi costanti, _Alignof espressioni e costanti galleggianti che sono i operandi immediati di calchi.

Per completezza, l'operatore sizeof non risulta sempre in espressione costante, anche se questo riguarda solo standard postali-C89 (C11 in VLA sono state fatte opzionale). Riferendosi a §6.5.3.4/p2 I sizeof e _Alignof operatori:

Se il tipo dell'operando è un tipo di matrice di lunghezza variabile, l'operando viene valutata; in caso contrario, l'operando non viene valutato e il risultato è una costante intera.

3

Per prima cosa, vediamo i criteri per un array (non è) un VLA. C11 doc, capitolo §6.7.6.2,

[...] Se la dimensione è un numero intero costante espressione e il tipo di elemento ha una dimensione costante noto, il tipo di matrice non è una lunghezza tipo array variabile ; [...]

Venendo al caso, sizeof è un operatore di compilazione, quindi produce un valore che è considerato la compilazione espressione costante. Una definizione di matrice, la cui dimensione è specificata come espressione della costante di tempo di compilazione, non è un VLA. Quindi, nel tuo codice,

int other_array[sizeof(array)] 

non è un VLA.

quanto riguarda il risultato sizeof operatore, da C11, capitolo §6.5.3.4, (sottolineatura mia)

L'operatore sizeof cede la dimensione (in byte) del suo operando, che può essere un'espressione o il nome tra parentesi di un tipo. [...] altrimenti, l'operando non viene valutato e il risultato è una costante intera.

+2

In C11 'sizeof' non è un" operatore di compilazione "e talvolta non produce un'espressione costante. (Sebbene OP chiedesse informazioni su C89) –

8

In ANSI C89 pseudonimo ISO C90, l'operatore sizeof produce un costante intera, che è adatto per dimensioni di matrice. Le chiamate di funzione, ad esempio, non lo sono.

Vorrei aggiungere un'altra osservazione, poiché ritengo che il codice così com'è abbia un problema che potrebbe essere trascurato.

Se il other_array viene dichiarata come

double other_array[sizeof(array)]; 

sarà né avere lo stesso numero di elementi, né la stessa dimensione (che sarebbe solo vero per array di char) come array[]. Se l'intento è di dichiarare una seconda matrice con lo stesso numero di elementi (indipendentemente dal tipo), utilizzare questo:

double other_array[sizeof(array)/sizeof(*array)]; 
+1

Perché il downvote? – Jens

+3

Non è il mio downvote, ma questa non è una risposta alla domanda. Questo dovrebbe essere un commento. –

+0

@JensGustedt Giusto abbastanza. Ma ho cercato effettivamente di capire che cosa avrebbe dovuto ottenere il codice, vedere più della domanda tecnica, scoprire perché qualcuno avrebbe voluto un altro array, il numero di elementi era uno per ogni byte in un doppio array. Non sembra giusto e i commenti sono semplicemente troppo limitati quando si tratta di formattazione. Forse dovrei ripetere la risposta tecnica una terza volta per conformarmi alle aspettative di risposta. – Jens

Problemi correlati