¿Qué devuelve sizeof (nombre de la función)?

Código de muestra:

main () { printf ("size = %d\n", sizeof (main)); } 

El estándar C lo prohíbe: cuando se comstack con gcc -pedantic , produce una invalid application of 'sizeof' to a function type advertencia de invalid application of 'sizeof' to a function type .

Sin embargo, gcc comstack y devuelve 1 para sizeof(main) , y no tiene el tamaño del puntero a la función.

Parece ser dependiente del comstackdor.

El tamaño del operador

  sizeof unary-expression sizeof ( type-name ) 

El operando es un identificador que es una expresión unaria, o una expresión de conversión de tipo (es decir, un especificador de tipo entre paréntesis). La expresión unaria no puede representar un objeto de campo de bit, un tipo incompleto o un function designator . El resultado es una constante integral sin signo. El encabezado estándar STDDEF.H define este tipo como size_t .

Utilice el indicador de comstackción -Wall -pedantic para emitir una advertencia sobre el operando incorrecto a sizeof (recuerde que sizeof es un operador de tiempo de comstackción), Código:

 $ cat sizeof.c #include int main(){ printf("%zu %p\n", sizeof(main), (void*)main); return 0; } 

Mensaje de comstackción con la versión 4.6.3 de GCC (Ubuntu / Linaro 4.6.3-1ubuntu5):

 $ gcc -Wall -pedantic sizeof.c -std=c99 sizeof.c: In function 'main': sizeof.c:3:30: warning: invalid application of 'sizeof' to a function type [-pedantic] sizeof.c:3:38: warning: ISO C forbids conversion of function pointer to object pointer type [-pedantic] 

Lea también:

6.5.3.4 El operador de sizeof

1118 – El operador sizeof no se aplicará a una expresión que tenga un tipo de función o un tipo incompleto, al nombre entre paréntesis de dicho tipo, oa una expresión que designe un miembro de campo de bit.
1127 – El valor del resultado está definido por la implementación, y su tipo (un tipo de entero sin signo) es size_t , definido en (y otros encabezados)

Además, la cadena de formato correcta para size_t es %zu y si no existe, por ejemplo, el comstackdor de Microsoft, puede usar %lu y convertir el valor devuelto en unsigned long .

ISO C ++ prohíbe la aplicación de sizeof a una expresión de tipo de función.

ISO / IEC 14882 en C ++ dice (sección 5.3.3):

“El operador de tamaño no se aplicará a una expresión que tenga función o tipo incompleto, …”

La misma retención para la sección 6.5.3.4 del estándar C (ISO / IEC 9899: 1999):

El operador sizeof no se aplicará a una expresión que tenga un tipo de función o un tipo incompleto, al nombre entre paréntesis de dicho tipo, o a una expresión que designe un miembro de campo de bit”.

Según ISO C11 sección 6.5.3.4 The sizeof and _Alignof operators , subsección 1 (restricciones):

El operador sizeof no se aplicará a una expresión que tenga un tipo de función o un tipo incompleto, al nombre entre paréntesis de dicho tipo, o a una expresión que designe un miembro de campo de bit.

También hay una subsección 4 en la sección 6.3.2.1 Lvalues, arrays, and function designators que dice:

Un designador de función es una expresión que tiene un tipo de función. Excepto cuando es el operando del operador sizeof , el operador _Alignof (65) o el operador unario, un designador de función con tipo “function returning type” se convierte a una expresión que tiene el tipo “puntero a función que devuelve type” “.

La nota de pie 65, a la que se hace referencia a partir de ahí, aclara el punto:

Debido a que esta conversión no ocurre, el operando del operador sizeof o _Alignof sigue siendo un designador de función y viola las restricciones en 6.5.3.4.

Según la sección 4 Conformance :

En esta norma internacional, “debe” debe interpretarse como un requisito en una implementación o en un progtwig; por el contrario, “no debe” debe interpretarse como una prohibición.

Por lo tanto, un progtwig estrictamente conformismo nunca debe tener el tamaño de una función. Pero, de nuevo, probablemente también debería usar una forma correcta de main() 🙂

Hay una laguna aquí, sin embargo. Una implementación conforme está autorizada a proporcionar extensiones “siempre que no alteren el comportamiento de ningún progtwig estrictamente conforme” (sección 4 Conformance , subsección 6 ).

Podría argumentar que se trata de un cambio de comportamiento (que permite el sizeof(function) lugar de rechazarlo), pero dado que el progtwig original no se habría ajustado estrictamente desde el principio, la subsección no lo prohíbe.