Quando controlliamo la dimensione di una funzione usando sizeof()
, otteniamo sempre 1 byte . Cosa significa questo 1 byte?
Quando controlliamo la dimensione di una funzione usando sizeof()
, otteniamo sempre 1 byte . Cosa significa questo 1 byte?
Risposte:
È una violazione dei vincoli e il tuo compilatore dovrebbe diagnosticare. Se lo compila nonostante ciò, il tuo programma ha un comportamento indefinito [grazie a @Steve Jessop per il chiarimento sulla modalità di errore, e vedi la risposta di @Michael Burr per il motivo per cui alcuni compilatori lo consentono]: Da C11, 6.5.3.4./ 1:
L'
sizeof
operatore non deve essere applicato a un'espressione con tipo di funzione
-std=c11
, no gnu11
. Questa è un'estensione del compilatore davvero strana.
sizeof(void)
è 1 in GNU C.
-std=c11
: qualcuno dovrebbe riferire le -std=c*
opzioni agli standard pubblicitari. Non abilitano la modalità di conformità, disabilitano semplicemente le estensioni che impedirebbero la compilazione di un programma ben formato (come typeof
essere una parola chiave, poiché un programma C ben formato può usarlo come nome di variabile, ma gcc
per impostazione predefinita lo rifiuterebbe ). Per disabilitare ulteriormente le estensioni che consentono a programmi mal formati di passare senza diagnosi, è necessario -pedantic
o -pedantic-errors
.
Questo non è un comportamento indefinito: lo standard del linguaggio C richiede una diagnostica quando si utilizza l' sizeof
operatore con un designatore di funzione (un nome di funzione) poiché è una violazione dei vincoli per l' sizeof
operatore.
Tuttavia, come estensione del linguaggio C, GCC consente l'aritmetica su void
puntatori e puntatori a funzione, che viene eseguita trattando la dimensione di void
ao come 1
. Di conseguenza, l' sizeof
operatore valuterà 1
per void
o una funzione con GCC. Vedi http://gcc.gnu.org/onlinedocs/gcc/Pointer-Arith.html#Pointer-Arith
È possibile fare in modo che GCC emetta un avviso quando si utilizza sizeof
con questi operandi utilizzando le opzioni -pedantic
o -Wpointer-arith
di GCC. Oppure commetti un errore con -Werror=pointer-arith
.
sizeof
affermato molto su UB tranne che una funzione non è UB (che ho menzionato praticamente solo perché altre risposte affermavano che era UB). Ma forse l'ho confuso a causa del modo in cui ho strutturato la frase. Per essere più chiari. sizeof
una funzione non è UB (come hanno affermato diverse risposte). È una violazione dei vincoli. In quanto tale, richiede una diagnosi. GCC lo consente come estensione.
Significa che l'autore del compilatore ha deciso un valore di 1 piuttosto che far volare i demoni dal tuo naso (in effetti, è stato un altro uso indefinito sizeof
che ci ha dato quell'espressione: "il compilatore C stesso DEVE emettere una diagnostica SE questa è la prima richiesta diagnostica risultante dal tuo programma, e quindi PU esso stesso far volare i demoni dal tuo naso (che, a proposito, potrebbe benissimo ESSERE il messaggio diagnostico documentato) così come POTREBBE emettere ulteriori diagnosi per ulteriori violazioni delle regole o dei vincoli della sintassi (o, del resto, per qualsiasi motivo scelga). " https://groups.google.com/forum/?fromgroups=#!msg/comp.std.c/ycpVKxTZkgw/S2hHdTbv4d8J
Da questo deriva il termine gergale "demoni nasali" per qualunque cosa un compilatore decida di fare in risposta a un costrutto indefinito. 1
è il demone nasale di questo compilatore per questo caso.
Come altri hanno sottolineato, sizeof () può accettare qualsiasi identificatore valido, ma non restituirà un risultato valido (onestamente vero e valido) per i nomi delle funzioni. Inoltre, può sicuramente, o meno, provocare la sindrome dei "demoni fuori dal naso".
Se vuoi profilare la dimensione della funzione del tuo programma, controlla la mappa del linker, che può essere trovata nella directory dei risultati intermedi (quella in cui le cose sono compilate in .obj / .o o dove si trova l'immagine / eseguibile risultante). A volte c'è un'opzione per generare o meno questo file di mappa ... dipende dal compilatore / linker.
Se vuoi la dimensione di un puntatore a una funzione, sono tutte della stessa dimensione, la dimensione di una parola di indirizzamento sulla tua cpu.
int x = 1;
ma solo uno di questi è consentito per un compilatore conforme agli standard. Con sizeof()
essere applicata a una funzione, si può o non può restituire un valore impostato, o rifiutare di compilazione, o restituire un valore casuale in base a ciò che c'è in un particolare registro al momento. I demoni nasali letterali sono improbabili, ma entro la lettera dello standard.
sizeof
a un puntatore a una funzione.
-pedantic
), hai un compilatore non conforme e ogni programma ha un comportamento indefinito.