Quando verificamos o tamanho de uma função usando sizeof()
, sempre obtemos 1 byte . O que significa este 1 byte?
87
É uma violação de restrição e seu compilador deve diagnosticar isso. Se ele compilar apesar disso, seu programa tem comportamento indefinido [obrigado a @Steve Jessop pelo esclarecimento do modo de falha e veja a resposta de @Michael Burr para saber por que alguns compiladores permitem isso]: De C11, 6.5.3.4./ 1:
O
sizeof
operador não deve ser aplicado a uma expressão que tenha tipo de função
-pedantic
), você tem um compilador não conforme e cada programa tem um comportamento indefinido.-std=c11
, nãognu11
. Esta é uma extensão de compilador realmente estranha.sizeof(void)
é feito com 1 no GNU C.-std=c11
: alguém deve referir as-std=c*
opções aos Padrões de Publicidade. Eles não habilitam o modo de conformidade, eles simplesmente desabilitam extensões que impediriam um programa bem formado de compilar (comotypeof
ser uma palavra-chave, já que um programa C bem formado pode usá-lo como um nome de variável, masgcc
por padrão rejeitaria isso ) Para desativar adicionalmente as extensões que permitem que programas malformados passem sem diagnóstico, você precisa de-pedantic
ou-pedantic-errors
.Este não é um comportamento indefinido - o padrão da linguagem C requer um diagnóstico ao usar o
sizeof
operador com um designador de função (um nome de função), pois é uma violação de restrição para osizeof
operador.No entanto, como uma extensão da linguagem C, o GCC permite aritmética em
void
ponteiros e ponteiros de função, o que é feito tratando o tamanho de umavoid
ou de uma função como1
. Como consequência, osizeof
operador avaliará1
paravoid
ou uma função com GCC. Consulte http://gcc.gnu.org/onlinedocs/gcc/Pointer-Arith.html#Pointer-ArithVocê pode fazer com que o GCC emita um aviso ao usar
sizeof
com esses operandos usando as opções-pedantic
ou-Wpointer-arith
do GCC. Ou cometa um erro com-Werror=pointer-arith
.fonte
sizeof
uma função não é UB (que eu mencionei basicamente apenas porque outras respostas afirmaram que era UB). Mas talvez eu tenha confundido isso devido à maneira como estruturei a frase. Para ser mais claro.sizeof
uma função não é UB (como várias respostas afirmam). É uma violação de restrição. Como tal, requer um diagnóstico. O GCC permite isso como uma extensão.Isso significa que o redator do compilador decidiu por um valor de 1 ao invés de fazer demônios voarem de seu nariz (na verdade, foi outro uso indefinido
sizeof
que nos deu a expressão: "o próprio compilador C DEVE emitir um diagnóstico SE este for o primeiro exigido diagnóstico resultante de seu programa e, em seguida, PODE fazer com que demônios voem de seu nariz (o que, a propósito, poderia muito bem SER a mensagem de diagnóstico documentada), assim como PODE emitir diagnósticos adicionais para novas violações de regras ou restrições de sintaxe (ou, nesse caso, por qualquer motivo que desejar). " https://groups.google.com/forum/?fromgroups=#!msg/comp.std.c/ycpVKxTZkgw/S2hHdTbv4d8JDisto existe a gíria "demônios nasais" para qualquer coisa que um compilador decida fazer em resposta a uma construção indefinida.
1
é o demônio nasal deste compilador para este caso.fonte
Como outros apontaram, sizeof () pode receber qualquer identificador válido, mas não retornará um resultado válido (um honestamente verdadeiro e válido) para nomes de função. Além disso, pode ou não resultar na síndrome de "demônios saindo do nariz".
Se você quiser traçar o perfil do tamanho da função do seu programa, verifique o mapa do vinculador, que pode ser encontrado no diretório de resultados intermediário (aquele onde as coisas são compiladas em .obj / .o ou onde a imagem / executável resultante está). Às vezes há uma opção de gerar ou não este arquivo de mapa ... é dependente do compilador / vinculador.
Se você quiser o tamanho de um ponteiro para uma função, eles são todos do mesmo tamanho, o tamanho de uma palavra de endereçamento em sua cpu.
fonte
int x = 1;
mas apenas um deles é permitido para um compilador compatível com os padrões. Aosizeof()
ser aplicada a uma função, ela pode ou não retornar um valor definido, ou se recusar a compilar, ou retornar um valor aleatório baseado no que quer que esteja em um determinado registro no momento. Demônios nasais literais são improváveis, mas dentro da letra do padrão.sizeof
a um ponteiro para uma função.