c++ - una - sizeof implementation
¿Sizeof(void()) es una expresión legal? (6)
De [5.3.3/1] , encontré que:
El operador sizeof no se aplicará a una expresión que tenga función o tipo incompleto
De [3.9/5] encontré que:
Los tipos de objeto incompletamente definidos y cv void son tipos incompletos
De todos modos, para
sizeof
no evalúa sus operandos, habría dicho que
sizeof(void())
era una expresión legal (en realidad, GCC lo compila y el resultado es 1).
Por otro lado, a partir de
here
,
void
no se menciona al discutir
sizeof
, ni cuando se mencionan los tipos que tienen tamaño 1, ni en la lista de los que tienen un tamaño
definido de implementación
.
La pregunta es así: ¿
sizeof(void())
una expresión legal?
¿Se garantiza que tenga un tamaño igual a 1?
¿O es una expresión legal que resulta en una UB y eso es todo?
Además, si compila el código, como en el ejemplo a continuación:
#include <iostream>
int main()
{
std::cout << sizeof(void());
}
El código se compila correctamente y produce un valor de 1, pero si observa la compilación, verá esto:
main.cpp: en la función ''int main ()'':
main.cpp: 5: 29: advertencia: aplicación no válida de ''sizeof'' a un tipo de función [-Wpointer-arith]
std :: cout << sizeof (void ());
Por lo tanto, es evidente que
sizeof()
no se aplica a los tipos de función, por lo que el código genera una advertencia.
Es inválido
Al mirar CppReference.com - sizeof operator , la documentación literalmente dice:
sizeof
no se puede usar con tipos de función , tipos incompletos o valores de campo de bits.
Y dado que
void()
es un tipo de función,
sizeof(void())
no es una expresión legal.
En su ejemplo de uso, podemos ver su comentario de error en esta línea:
std::cout << "size of function: " << sizeof(void()) << ''/n''; // error
Como ya se destacó en los documentos aquí http://en.cppreference.com/w/cpp/language/sizeof
Notas
sizeof()
no se puede usar con
tipos de función
, tipos incompletos o valores de campo de bits.
Como
void()
es un tipo de función, no es un tipo válido de
sizeof()
Nota:
void()
es una función que no toma argumentos y no devuelve nada
Citando un ejemplo de documentos:
//<< "size of function: " << sizeof(void()) << ''/n'' // error
Entonces respuestas a sus preguntas:
1) No, no es una expresión legal.
2) Se mostrará como 1, pero mostrará una advertencia
3) igual que 1).
Straigth de la referencia C99 NO
Enunciado en el documento en la sección 6.5.3.4 El tamaño del operador :
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 ni a una expresión que designe un miembro de campo de bits.
De acuerdo con los ítems 19 y 20 de la sección 6.2.5 Tipos :
- El tipo vacío comprende un conjunto vacío de valores; Es un tipo incompleto que no se puede completar.
- ... Un tipo de función describe una función con el tipo de retorno especificado. Un tipo de función se caracteriza por su tipo de retorno y el número y tipos de sus parámetros. Se dice que un tipo de función se deriva de su tipo de retorno, y si su tipo de retorno es T, el tipo de función a veces se denomina "función de retorno T". La construcción de un tipo de función a partir de un tipo de retorno se denomina "derivación del tipo de función".
Por lo tanto, void () es un tipo de función derivado de un tipo incompleto y es ilegal como operando para el tamaño de. Dicho esto, sus retornos dependerán de la implementación del compilador y no tienen ningún valor de retorno garantizado.
Una pequeña premisa.
La pregunta surgió de una mala interpretación del
sizeof
operador.
De hecho, el OP consideró
void()
una expresión que tiene un tipo incompleto en el contexto de
sizeof
y la pregunta en sí misma puede leerse como:
¿por qué
sizeof
acepta la expresión
void()
, que es un tipo incompleto y no debe aceptarse como se menciona en el borrador de trabajo
?
Es por eso que se menciona [3.9 / 5] en realidad, de lo contrario no habría tenido sentido.
Dicho esto, el hecho es que la pregunta contiene en realidad dos preguntas interesantes:
-
¿Por qué
sizeof(void())
no es legal?
Esta es la pregunta real a partir del título en sí. -
¿Por qué
sizeof((void()))
no es legal?
Esta es la pregunta prevista del PO.
Respuestas abajo:
-
void()
ensizeof(void())
se interpreta como un tipo de función y está mal formado como para [5.3.3/1] (énfasis mío):El operador sizeof no se aplicará a una expresión que tenga función o tipo incompleto , al nombre entre paréntesis de tales tipos , [...]
-
(void())
ensizeof((void()))
es una expresión que tiene un tipo devoid
incompleto (tenga en cuenta quesizeof
es un contexto no evaluado) y está mal formado como para [5.3.3/1] (énfasis mío) :El operador sizeof no se aplicará a una expresión que tenga función o tipo incompleto , al nombre entre paréntesis de tales tipos, [...]
En ambos casos, GCC compila el código con una advertencia.
void()
es un tipo de función (es una función que no toma argumentos y no devuelve nada), por lo que no es un tipo válido en
sizeof()
.