Cuando verificamos el tamaño de una función usando sizeof()
, siempre obtenemos 1 byte . ¿Qué significa este 1 byte?
Cuando verificamos el tamaño de una función usando sizeof()
, siempre obtenemos 1 byte . ¿Qué significa este 1 byte?
Respuestas:
Es una infracción de restricción y su compilador debería diagnosticarla. Si lo compila a pesar de eso, su programa tiene un comportamiento indefinido [gracias a @Steve Jessop por la aclaración del modo de falla, y vea la respuesta de @Michael Burr por qué algunos compiladores permiten esto]: De C11, 6.5.3.4./ 1:
El
sizeof
operador no se aplicará a una expresión que tenga el tipo de función
-std=c11
, no gnu11
. Esta es una extensión de compilador realmente extraña.
sizeof(void)
es 1 en GNU C.
-std=c11
: alguien debería referir las -std=c*
opciones a los Estándares Publicitarios. No habilitan el modo de conformidad, simplemente deshabilitan las extensiones que evitarían la compilación de un programa bien formado (como typeof
ser una palabra clave, ya que un programa C bien formado puede usarlo como un nombre de variable, pero gcc
por defecto rechazaría eso ). Para deshabilitar adicionalmente las extensiones que permiten que programas mal formados pasen sin ser diagnosticados, necesita -pedantic
o -pedantic-errors
.
Este no es un comportamiento indefinido: el estándar del lenguaje C requiere un diagnóstico cuando se usa el sizeof
operador con un designador de función (un nombre de función), ya que es una violación de restricción para elsizeof
operador.
Sin embargo, como una extensión del lenguaje C, GCC permite aritmética en void
punteros y punteros de función, lo cual se hace tratando el tamaño de void
una función como 1
. Como consecuencia, el sizeof
operador evaluará 1
para void
o una función con GCC. Ver http://gcc.gnu.org/onlinedocs/gcc/Pointer-Arith.html#Pointer-Arith
Puede hacer que GCC emita una advertencia al usar sizeof
estos operandos usando las opciones -pedantic
o -Wpointer-arith
para GCC. O conviértalo en un error con -Werror=pointer-arith
.
sizeof
una función no es UB (que mencioné prácticamente solo porque otras respuestas indicaron que era UB). Pero tal vez lo confundí por la forma en que estructuré la oración. Para ser más claro. sizeof
una función no es UB (como han afirmado varias respuestas). Es una violación de la restricción. Como tal, requiere un diagnóstico. GCC lo permite como una extensión.
Significa que el escritor del compilador decidió un valor de 1 en lugar de hacer que los demonios vuelen de su nariz (de hecho, fue otro uso indefinido de lo sizeof
que nos dio esa expresión: "el compilador de C DEBE emitir un diagnóstico SI este es el primero requerido diagnóstico resultante de su programa, y luego PUEDE hacer que los demonios salgan volando de su nariz (que, por cierto, bien podría SER el mensaje de diagnóstico documentado) al igual que PUEDE emitir diagnósticos adicionales para más violaciones de las reglas o restricciones de sintaxis (o, para el caso, por cualquier motivo que elija) ". https://groups.google.com/forum/?fromgroups=#!msg/comp.std.c/ycpVKxTZkgw/S2hHdTbv4d8J
A partir de esto, hay un término de jerga "demonios nasales" para cualquier cosa que un compilador decida hacer en respuesta a una construcción indefinida. 1
es el demonio nasal de este compilador para este caso.
Como otros señalaron, sizeof () puede tomar cualquier identificador válido, pero no devolverá un resultado válido (honestamente verdadero y válido) para los nombres de funciones. Además, definitivamente puede, o no, resultar en el síndrome de "demonios fuera de la nariz".
Si desea perfilar el tamaño de la función de su programa, verifique el mapa del enlazador, que se puede encontrar en el directorio de resultados intermedios (aquel donde se compilan las cosas en .obj / .o o donde se encuentra la imagen / ejecutable resultante). A veces hay una opción para generar o no este archivo de mapa ... depende del compilador / enlazador.
Si quisiera el tamaño de un puntero a una función, todos son del mismo tamaño, el tamaño de una palabra de direccionamiento en su CPU.
int x = 1;
pero solo uno de ellos está permitido para un compilador compatible con los estándares. Al sizeof()
aplicarse a una función, puede devolver o no un valor establecido, o negarse a compilar, o devolver un valor aleatorio basado en lo que sea que esté en un registro particular en ese momento. Los demonios nasales literales son poco probables, pero dentro de la letra del estándar.
sizeof
a un puntero a una función.
-pedantic
), tiene un compilador no conforme y cada programa tiene un comportamiento indefinido.