Es sizeof(void()) una expresión jurídica?
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 objetos definidos de forma incompleta y cv void son tipos incompletos
De todos modos, para sizeof
no evalúa sus operandos, yo habría dicho que sizeof(void())
era una expresión legal (en realidad GCC lo compila y el resultado es 1).
En el otro lado, desde aquí, void
no se menciona mientras se discute sizeof
, ni cuando se mencionan los tipos que tienen tamaño 1, ni en la lista de los que tienen un tamaño definido por la implementación.
La pregunta es: ¿es sizeof(void())
una expresión legal?
¿Está garantizado que tenga un tamaño igual a 1?
¿O es una expresión legal que resulta en una UB y eso es todo?
6 answers
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()
.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-09-01 18:12:26
De mirar CppReference.com -tamaño del operador, la documentación dice literalmente:
sizeof
no se puede utilizar con tipos de función , tipos incompletos, o glvalues de campo de bits.
Y dado que void()
es un tipo de función, entonces sizeof(void())
no es una expresión legal.
En su ejemplo de uso, podemos ver su error comentario en esta línea:
std::cout << "size of function: " << sizeof(void()) << '\n'; // error
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-09-01 20:43:24
También, si compila el código, como el siguiente ejemplo:
#include <iostream>
int main()
{
std::cout << sizeof(void());
}
El código compila correctamente y produce un valor de 1, pero si miras la compilación, verás esto:
Main.cpp: In function ' int main ()':
Main.cpp: 5: 29: advertencia: aplicación inválida de' sizeof ' a un tipo de función [- Wpointer-arith]
Std:: cout
Por lo tanto, es evidente que sizeof()
no se aplica a los tipos de función, por lo que el código produce un advertencia. No es válido.
Código aquí
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-09-01 18:57:19
Una pequeña premisa.
La pregunta surgió de una mala interpretación del operador sizeof
.
De hecho, el PO consideró void()
una expresión que tiene un tipo incompleto en el contexto de sizeof
y la pregunta en sí puede leerse como - ¿por qué sizeof
aceptar 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 [3.9/5] se menciona en realidad, de lo contrario no habría tenido sentido.
Que dijo, 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 mismo.¿Por qué
sizeof((void()))
no es legal?
Esta es la cuestión prevista de la OP.
Respuestas a continuación:
-
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 el tipo function o incomplete , al nombre entre paréntesis de dichos tipos, [...]
-
(void())
ensizeof((void()))
es una expresión que tiene un tipo incompletovoid
(tenga en cuenta quesizeof
es un contexto no evaluado) y está mal formada en cuanto a [5.3.3/1] (énfasis mío):El operador sizeof no se aplicará a una expresión que tenga la función o tipo incompleto , al nombre entre paréntesis de dichos tipos, [...]
En ambos casos GCC compila el código con una advertencia.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-09-11 20:56:51
Como ya se ha resaltado 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 glvalues de campo de bits.
Dado que void()
es un tipo de función, por lo que 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
Así que las respuestas a su preguntas:
1) No no es una Expresión legal.
2) Se mostrará como 1 , pero mostrará una advertencia
3) igual que 1).
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-09-08 08:54:03
Directamente desde el número de referencia C99
Indicado 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, o a una expresión que designe un miembro de campo de bits.
De acuerdo con los puntos 19 y 20 de la sección 6.2.5 Tipos :
- El tipo void 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 un 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 llama "función que devuelve T". La construcción de un tipo de función a partir de un tipo de retorno se denomina " tipo de función derivation".
Así void() es un tipo de función derivado de un tipo incompleto y es ilegal como operando para el sizeof. Dicho esto, sus retornos dependerán de la implementación del compilador y no tienen ningún valor de retorno garantizado
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-09-11 10:09:53