2010-10-17 14 views
6

C++ ANSI ISO IEC 14882 2003 Allegato C.1 (Pagina 668):lvalue-to-rvalue conversione di un array in C ISO

Modifica: Il risultato di un'espressione condizionale, un'espressione di assegnazione, o una virgola espressione may bean lvalue
Razionale: C + + è un linguaggio orientato agli oggetti, che pone un'enfasi relativamente maggiore sugli lvalue. Ad esempio, le funzioni possono restituire lvalue.
Effetto sulla funzione originale: passa alla semantica di una funzione ben definita. Alcune espressioni C che implicitamente fanno affidamento sulle conversioni da lvalue a rvalue produrranno risultati diversi. Ad esempio,

char arr[100]; 
sizeof(0, arr) 

cede 100 in C + + e sizeof(char*) in C.
...

stavo leggendo questo proprio oggi e mi sono ricordato che un paio di mesi un andare un mio amico ha proposto un problema per scrivere una funzione che restituirebbe 0 se fosse compilato con C++ e 1 se fosse compilato con C. L'ho risolto sfruttando il fatto che in C una struct era nello scope esterno. Quindi, considerando questa nuova informazione, ho deciso che questa sarebbe stata un'altra soluzione al problema precedente, che ho provato su Microsoft Visual Studio 2008, ma indipendentemente dal fatto che sia compilato come codice C o C++ sizeof(0, arr) restituisce sempre 4. Quindi 2 domande:

1. Cos'è ISO C? È lo standard C attuale? È l'unico (sento che C è in rapida evoluzione) 2. Si tratta di un bug microsoft C++?

TIA

Edit: Scusa ottenuto mescolato con l'uscita ed averla modificata:

+1

Con MSVC 2010, 'sizeof (0, arr)' sembra valutare a '4' (quando compilato come C++). Con g ++, valuta a '100'. –

risposta

1

O semplicemente C di Microsoft non è ISO C ma qualche altro standard C (se esiste).

Microsoft Visual C supporta ancora C89 [solo] mentre altri compilatori come gcc/clang ecc supportano anche C99 che è lo standard corrente.

C99 [Sezione 6.5.17/2] dice

L'operando a sinistra di un operatore virgola viene valutata come espressione vuoto; c'è un punto di sequenza dopo la sua valutazione. Quindi viene valutato l'operando destro; il risultato ha il suo tipo e valore.

questo il risultato della sizeof (0,arr) sarebbe sizeof(char*) [dovuto al implicito lvalue a rvalue conversione/decadimento automatico di tipo puntatore] non 100*sizeof(char)

sizeof(arr) avrebbe dato 100*sizeof(char) da 6.5.3.4/3

95) Un operatore virgola non produce un lvalue.


deciso che questa sarebbe un'altra soluzione al problema di cui sopra, che ho provato su Microsoft Visual Studio 2008, ma a prescindere dal fatto che sia compilato come C o C++ Codice sizeof (0, arr) sempre rendimenti 4.

C++ 03 [5.18/1] virgola operatore

il tipo e valore del risultato sono il tipo e valore dell'operando di destra; il risultato è un lvalue se il suo operando è corretto.

Così sizeof(0, arr) = sizeof (arr) e che sarebbe uguale a 100* sizeof(char) e non = sizeof(char*).

Quindi MSVC++ fornisce risultati errati (nel caso del codice C++).

+0

@Prasoon: il 95) si riferisce a C o C++? –

+0

@Armen: 'C99' [..] Modificato il mio post per chiarezza. –

+0

A volte mi chiedo perché sto ancora utilizzando MSVC. Ma poi hanno un IDE fantastico ... –

5

ISO C è lo standard C. Quello attuale è C99 ma C1x è proprio dietro l'angolo. Se da una rapida, si intende un nuovo standard ogni dieci anni o giù di lì, allora sì, si sta rapidamente :-)

Sezione 6.5.3.4/3 di ISO C99 evolvendo afferma:

Quando viene applicato a un operando che ha tipo char, unsigned char, o firmato char, (o una versione qualificata) il risultato è 1.

Quando applicato a un operando con tipo di matrice, il risultato è il numero totale di byte nell'array .

0

Per gli array, lo sizeof restituisce la dimensione totale. Fai attenzione agli array passati come puntatori.

C99 norma:

Quando applicato ad un operando che ha matrice tipo, il risultato è il numero totale di byte nella matrice