Quando verificamos o tamanho de uma função usando sizeof()
, sempre obtemos 1 byte . O que significa este 1 byte?
Quando verificamos o tamanho de uma função usando sizeof()
, sempre obtemos 1 byte . O que significa este 1 byte?
Respostas:
É 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
-std=c11
, não gnu11
. 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 (como typeof
ser uma palavra-chave, já que um programa C bem formado pode usá-lo como um nome de variável, mas gcc
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 o sizeof
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 uma void
ou de uma função como 1
. Como consequência, o sizeof
operador avaliará 1
para void
ou uma função com GCC. Consulte http://gcc.gnu.org/onlinedocs/gcc/Pointer-Arith.html#Pointer-Arith
Você 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
.
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/S2hHdTbv4d8J
Disto 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.
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.
int x = 1;
mas apenas um deles é permitido para um compilador compatível com os padrões. Ao sizeof()
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.
-pedantic
), você tem um compilador não conforme e cada programa tem um comportamento indefinido.