Nella maggior parte dei casi (in C almeno), lo sizeof(*x)
non valuta affatto lo *x
. Lo standard C99 ha questo da dire in 6.5.3.4 The sizeof operator
, parte /2
(mio grassetto):
L'operatore sizeof cede la dimensione (in byte) del suo operando, che può essere un'espressione o il nome parentesi di un tipo. La dimensione è determinata dal tipo dell'operando. Il risultato è un numero intero. Se il tipo dell'operando è un tipo di array di lunghezza variabile, viene valutato l'operando; altrimenti, l'operando non viene valutato e il risultato è una costante intera.
Quindi, per tutti i non VLA, non avviene alcun dereferenziamento. Se il tipo di *x
è un VLA, questa è considerata una fase di esecuzione sizeof
, qualcosa che deve essere elaborato mentre il codice è in esecuzione - tutti gli altri possono essere calcolati in fase di compilazione.
C++ ha regole leggermente diverse, come mostrato in 5.3.3. Sizeof
, parte /1
:
L'operatore sizeof restituisce il numero di byte nella rappresentazione dell'oggetto del suo operando. L'operando è un'espressione, che è un operando non valutato (clausola 5) o un id-tipo parentesi.
5. Expressions
definisce il termine "operando non valutata" in parte /8
:
In alcuni contesti, appaiono operandi non valutate. Un operando non valutato non viene valutato.
(forse una delle frasi inutili e ridondanti che ho letto per un po ', ma non so cosa stesse passando per la mente degli ISO quando lo hanno scritto).
Per completezza, in C++ (che non ha VLAs) l'espressione non viene mai valutata: C++ 11, 5.3.3 dice "L'operando è o un'espressione, che è un operando non valutato (Clausola 5), o una parentesi tipo-id ". –
Cheers, @Mike, l'hanno incorporato nella risposta per completezza. – paxdiablo