2015-06-24 24 views
19

So che sizeof non valuta mai il suo operando, tranne nel caso specifico in cui detto operando è un VLA. Oppure, I pensato lo sapevo.VLA e effetti collaterali nell'operando sizeof

void g(int n) { 
    printf("g(%d)\n", n); 
} 

int main(void) { 
    int i = 12; 

    char arr[i]; // VLA 

    (void)sizeof *(g(1), &arr); // Prints "g(1)" 
    (void)sizeof (g(2), arr); // Prints nothing 

    return 0; 
} 

Cosa sta succedendo?

Nel caso, questo è compilato con GCC 5.1 su Coliru.

risposta

18

Sembra che dovrei pensarci due volte prima di postare, perché mi ha colpito subito dopo averlo fatto.

La mia comprensione di come sizeof interagisce con i VLA è in realtà corretto, come le seguenti conferma di citazione (grazie!) @This:

6.5.3.4 Gli operatori sizeof e _Alignof
Se il tipo dell'operando è un tipo di array a lunghezza variabile, viene valutato l'operando; altrimenti, l'operando non viene valutato e il risultato è una costante intera

Questo non è ciò che sta causando questo sorprendente (per me) comportamento.

(void)sizeof (g(2), arr); 

Nel (g(2), arr) sottoespressione, l'operatore virgola innesca arr s' array a puntatore decadimento. Pertanto, l'operando di sizeof non è più un VLA, ma un semplice char* e ricade indietro per non valutare il suo operando.

Apparently questo comportamento è stato modificato in C++, dove l'operatore virgola non decadrà più gli array.

+2

Per una volta, un buon caso per rispondere alla tua stessa domanda. – Bathsheba

+2

Si potrebbe voler aggiungere questo da qualche parte: * 6.5.3.4 Gli operatori sizeof e _Alignof Se il tipo dell'operando è un tipo di array di lunghezza variabile , l'operando viene valutato; altrimenti, l'operando non viene valutato e il risultato è una costante intera di *, pertanto i lettori di febbre verranno confusi. – this

+0

@this Grazie :) – Quentin

Problemi correlati