Ответ 1
Конверсии с типом void
, а также возможность возврата значения void
с самого начала присутствуют на языке С++. Единственная проблема, которая вызывает вопросы, - это роль {}
в этом контексте.
Быстрый эксперимент с clang
int a({});
генерирует сообщение об ошибке
error: cannot initialize a variable of type 'int' with an rvalue of type 'void'
который указывает, что clang интерпретирует {}
как значение void
. Это, по-видимому, нестандартное поведение. Я не вижу места в спецификации языка, который сказал бы, что {}
должен давать значение void
в этом контексте.
Но так как это происходит в clang, нет ничего необычного в компиляции void({})
в clang. Любое значение в С++ может быть преобразовано в тип void
, что означает, что до тех пор, пока компилятор принимает {}
в этом контексте, остальное просто следует естественным образом.
В GCC на самом деле это ошибка в режиме -pedantic-errors
error: list-initializer for non-class type must not be parenthesized
так формально это "ошибка", а не "предупреждение" в GCC.
Что на самом деле происходит здесь, так это то, что комбинация открытия ({
и закрытия })
заставляет эти компиляторы интерпретировать его как расширение языка GNU C, известное как Выражение выражений (кстати, также поддерживается clang). Это, например, то, что делает следующий код компиляции
int a = ({ 3; });
В этом расширении выражение ({})
рассматривается как выражение выражения типа void
. Однако это конфликтует с синтаксисом равномерной инициализации в С++.