2012-12-28 18 views
7

Eventuali duplicati:
Variably modified array at file scopearray lunghezza variabile (VLA) in C e C++

Ho alcuni concetti riguardanti la VLA e il suo comportamento che ho bisogno di chiarire.

Afik dal C99 è possibile dichiarare VLA in ambiti locali:

int main(int argc, char **argv) 
{ 
    // function 'main' scope 
    int size = 100; 
    int array[size]; 
    return 0; 
} 

ma è vietato in ambiti globali:

const int global_size = 100; 
int global_array[global_size]; // forbidden in C99, allowed in C++ 

int main(int argc, char **argv) 
{ 
    int local_size = 100; 
    int local_array[local_size]; 
    return 0; 
} 

Il codice di cui sopra dichiara un VLA nel C99, perché il modificatore const non crea un valore in fase di compilazione. In C++ global_size è un valore in fase di compilazione quindi, global_array non diventa VLA.

Quello che devo sapere è: il mio ragionamento è corretto? Il comportamento che ho descritto è corretto?

Voglio anche sapere: perché il VLA in ambito globale non è consentito? sono proibiti sia in C che in C++? Qual è la ragione per cui il comportamento degli array in ambito globale e locale era diverso?

+5

Supponiamo che siano consentiti gli VLA globali. Quando viene definita la loro dimensione (variabile)? – cnicutar

+0

@cnicutar bene ... come tutto il VLA, in tempo di esecuzione, come gli altri ambiti. So che questa non è la risposta, ma voglio sapere PERCHE '. –

+1

http://stackoverflow.com/a/5052083/174605 – coelhudo

risposta

5

Sì, il tuo ragionamento è corretto, questo è il modo in cui queste diverse forme di dichiarazioni e definizioni di array vengono visualizzate da C e C++.

Come altri già affermato, VLA con una lunghezza variabile reale (non const) in ambito globale è difficile da comprendere. Quale sarebbe l'ordine di valutazione, ad esempio se l'espressione di lunghezza si riferirebbe a un oggetto di una diversa unità di compilazione? C++ non ha VLA, ma ha l'inizializzazione dinamica degli oggetti nell'ambito del file. E già questo ti dà un bel mal di testa, se devi fare affidamento sull'ordine di valutazione.

Lascia il piccolo spazio per C relativo alle espressioni di lunghezza che contengono un oggetto qualificato const, che non è consentito. Ciò deriva dal fatto che tali oggetti non sono considerati "espressioni costanti intere" dallo standard C. Questo potrebbe forse cambiare nelle versioni future, ma fino ad ora il comitato C non ha ritenuto necessario consentire una cosa del genere: ci sono le costanti enum che svolgono tale ruolo in C. La loro unica limitazione è che sono limitate a int in C, sarebbe bello averli anche size_t.

+0

Finalmente qualcuno dimostra di aver letto l'intera domanda! (+1 per questo) IMHO questa domanda non è [duplicata] (http://stackoverflow.com/questions/1712592/variably-modified-array-at-file-scope) perché mi sto concentrando su altri fatti. Grazie per la spiegazione e grazie per aver risposto a quasi tutte le mie domande. –

1

C'è una differenza tra l'essere vietato e il non permesso. ;-)

La funzione VLA è progettata per consentire l'uso dello spazio di stack per un array locale, per evitare l'uso di malloc per l'allocazione dell'heap. È principalmente un'ottimizzazione della velocità.

Ora si desidera utilizzare VLA al di fuori delle funzioni. Perché? Non c'è molto da guadagnare in senso orario evitando una singola chiamata malloc durante l'avvio del programma. E quale spazio di pila dovremmo usare per le variabili con una durata statica?

3

Penso che la ragione fondamentale sia una variabile globale che ha un collegamento, la sua dimensione deve essere nota al momento della compilazione. In caso contrario, come si potrebbe collegare il programma?

Le variabili locali non hanno alcun collegamento e gli VLA sono allocati nello stack, che cresce dinamicamente durante l'esecuzione del programma.

2

C++ non supporta VLA, punto. La ragione per cui il secondo frammento di codice funziona in C++ è che la parola chiave const crea una costante in fase di compilazione in C++; in C, non è così.

C99 non supporta VLA al di fuori dell'ambito del blocco, periodo, indipendentemente da come si dichiara la variabile di dimensione. Notare che C2011 rende opzionale il supporto VLA.

+0

Sì, so che la parola chiave 'const' crea una costante in fase di compilazione in C++ e in C no, ho commentato questa domanda. –

1

Quindi, per il mondiale di VLA, uno dei temi (ci sono molte varianti sul tema) può essere visualizzata qui:

int size; 
int a; 
int v[size]; 
int b; 

.... in un altro file:

extern int a; 
extern int b; 

Il linker dovrà sapere dove si e sono in relazione tra loro al momento del collegamento, o non sarà in grado di correggerli correttamente al momento del caricamento.