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?

Author: BЈовић, 2016-09-01

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().

 57
Author: Some programmer dude,
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
 40
Author: Khalil Khalaf,
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í
 9
Author: Arnav Borborah,
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() en sizeof(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()) en sizeof((void())) es una expresión que tiene un tipo incompleto void (tenga en cuenta que sizeof 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.

 6
Author: skypjack,
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).

 1
Author: Cold Fire,
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 :

  1. El tipo void comprende un conjunto vacío de valores; es un tipo incompleto que no se puede completar.
  2. ...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

Norma C99

 1
Author: WelsonJR,
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