2009-11-15 19 views
15

Perché l'espressione specificata all'interno di un operatore virgola (come nell'esempio seguente) non è considerata un'espressione costante?Operatore virgola C

Ad esempio,

int a = (10,20) ; 

quando somministrato nell'ambito globale produce un errore "inizializzatore non è una costante", se entrambe le espressioni separate da un operatore virgola sono costanti (espressioni costanti). Perché l'intera espressione non è trattata come un'espressione costante? Per chiarimenti, ho letto What does the ‘,’ operator do in C? e Uses of C comma operator. Non hanno affrontato questo aspetto dell'operatore virgola.

+0

Grazie Rossel. Ora il testo ha una maggiore leggibilità. –

+0

possibile duplicato di [Cosa fa l'operatore virgola \ ', \' do in C?] (Http://stackoverflow.com/questions/52550/what-does-the-comma-operator-do-in-c) –

risposta

33

Sezione 6.6/3, "Espressioni costanti", dello standard ISO C99 è la sezione richiesta. Essa afferma:

espressioni costanti non devono contenere l'assegnazione, incremento, decremento, la funzione chiamata, o virgola gli operatori, tranne quando sono contenuti all'interno di una sottoespressione che non è valutata.

Nel documento logica C99 da ISO, c'è questo piccolo frammento:

Un numero intero espressione costante deve coinvolgere solo numeri conoscibili al momento della traduzione, e operatori senza effetti collaterali.

E, dal momento che non c'è nessun punto nel usando l'operatore virgola affatto se non stai basandosi su effetti collaterali, è inutile in un'espressione costante.

Con questo, voglio dire non c'è assolutamente nessuna differenza tra i due segmenti di codice:

while (10, 1) { ... } 
while  (1) { ... } 

dal momento che il 10 in realtà non lo fanno nulla. In realtà,

10; 

è un perfettamente valido, anche se non molto utile, economico c, qualcosa che la maggior parte delle persone non capiscono fino a quando si arriva a conoscere meglio la lingua.

Tuttavia, v'è una differenza tra queste due affermazioni:

while ( 10, 1) { ... } 
while (x=10, 1) { ... } 

C'è un effetto collaterale in quest'ultimo uso dell'operatore virgola che deve impostare la variabile x a 10.

Sul motivo per cui non amano gli effetti collaterali nelle espressioni costanti, l'intero punto delle espressioni costanti è che possono essere valutati in fase di compilazione senza richiedere un ambiente di esecuzione - ISO distingue tra traduzione (tempo di compilazione) e ambienti di esecuzione (runtime).

L'indizio sul perché ISO decise di richiedere compilatori per fornire informazioni ambiente di esecuzione (diverso da cose contenute nei file di intestazione, come limits.h) si può trovare un po 'più tardi nel documento logica:

Tuttavia, mentre le implementazioni sono certamente consentite per produrre esattamente lo stesso risultato negli ambienti di traduzione e di esecuzione, richiedendo che ciò fosse ritenuto un onere intollerabile per molti cross-compilatori.

In altre parole, ISO non voleva che i produttori di cross-compilatori fossero gravati da un ambiente di esecuzione per ogni possibile obiettivo.

+5

+1: stavo solo cercando questo. Credo che la ragione più approfondita sia che l'operatore virgola introduce un punto di sequenza. –

+0

Grazie paxdiablo. Il riferimento a un documento razionale è quello che ho richiesto per chiarire il mio dubbio. –

-2

gcс accetta questa:

int a = (10,20) ; 

int main() { 
    printf("%d\n",a); 
} 

e stampe 20. Probabilmente è un problema del tuo compilatore?

+0

Il mio gcc (4.3.3), senza bandiere, non lo accetta. –

+0

Quale versione di GCC su quale piattaforma con quali flag? Ho provato con GCC 4.0.1 su MacOS X 10.5.8 senza bandiere e ho ricevuto l'errore. –

+0

gcc versione 3.4.4 (speciale cygming, gdc 0.12, usando dmd 0.125) Cygwin, senza bandiere. –

6

ISO/IEC 9899: 1999 6.6/3 (espressioni costanti) afferma che le espressioni contant non devono contenere operatori virgola (a meno che parte di una sotto-espressione non venga valutata), quindi (10,20) non è un'espressione costante per definizione .

La logica deve essere che, poiché il valore della prima parte dell'espressione virgola non viene utilizzato, è presente solo per i suoi effetti collaterali e non ha senso che le espressioni costanti abbiano effetti collaterali.

0

Il compilatore non considera un'espressione costante poiché la variabile è automatica. È consentito essere valutato in fase di esecuzione e ottenere un valore. Prova a rendere la variabile statica e vedrai lo stesso messaggio di errore in quanto il compilatore richiederà un'espressione costante in quel momento.