for c++ gcc clang c++14 language-lawyer

c++ - for - llvm download windows



¿Qué es{} en void({})? (1)

Las conversiones a tipo de void así como la posibilidad de devolver un valor de void han estado presentes en el lenguaje C ++ desde el principio. La única parte que plantea preguntas es el rol de {} en este contexto.

Un experimento rápido con clang.

int a({});

genera un mensaje de error diciendo

error: cannot initialize a variable of type ''int'' with an rvalue of type ''void''

lo que indica que clang interpreta {} como un valor void . Esto parece ser un comportamiento no estándar. No veo ningún lugar en la especificación de lenguaje que diga que {} debe producir un valor void en este contexto.

Pero dado que este es el caso de Clang, no hay nada inusual en la compilación de void({}) en Clang. Cualquier valor en C ++ se puede convertir a un tipo void , lo que significa que siempre que el compilador acepte {} en este contexto, el resto simplemente lo seguirá de forma natural.

En GCC es en realidad un error en el -pedantic-errors

error: list-initializer for non-class type must not be parenthesized

así que formalmente es un "error", no una "advertencia" en GCC.

Lo que realmente sucede aquí es que la combinación de apertura ({ y cierre }) hace que estos compiladores lo interpreten como una extensión del lenguaje C GNU conocida como Expresión de Expresión (que también es compatible con el Clang). Esto es, por ejemplo, lo que hace que el siguiente código se compile

int a = ({ 3; });

Bajo esa extensión, la expresión ({}) se ve como una expresión de declaración de tipo void . Sin embargo, esto entra en conflicto con la sintaxis de inicialización uniforme en C ++.

Considere el siguiente fragmento de código:

auto f() { return void({}); } int main() { f(); }

¿Qué es exactamente el {} en void({}) ?
¿Cómo se interpreta?

Solo por curiosidad, por supuesto. Vayamos un poco más lejos de todos modos.

Tenga en cuenta que tanto GCC 6.1 como clang 3.8 lo compilan sin errores ( -std=c++14 -pedantic ).
El último no se queja, el primero muestra una advertencia:

advertencia: el inicializador de lista para un tipo que no sea de clase no debe estar entre paréntesis

Usando -pedantic-errors lugar, GCC termina con un error mientras Clang lo compila.

¿Es esta discrepancia un error de uno de los dos compiladores?
Quiero decir, ¿es un código válido que debería ser aceptado o no?