Разница между разбором void() и int()

Прочитав о самом неприятном разборе, я немного поэкспериментировал и нашел эту программу. Есть две очень похожие строки. Один из них выдает предупреждения как в g++7, так и в clang++-3.9, другой - нет.

int main() {
  void(); // no warning
  int(); // warning: statement has no effect
}

Во второй строке построенный по умолчанию объект типа int создается и немедленно уничтожается, поэтому не используется. Но что происходит в первой строке? Если он был проанализирован таким же образом, это должно быть ошибкой, поскольку создание объекта типа недопустимо void, С другой стороны, это не похоже на объявление функции.

2 ответа

Решение

Нет разницы в разборе. Оба случая охватываются спецификатором простого типа, за которым следует необязательный список выражений в скобках.

Семантическое значение определено в C++17 (N4659) [expr.type.conv]/2:

Если тип cv void и инициализатор () выражение является значением указанного типа, которое не выполняет инициализацию. В противном случае выражение является prvalue указанного типа, чей результирующий объект инициализируется напрямую с помощью инициализатора.

Это конкретно говорит о том, что void() это значение типа void,

Теперь я уверен, что не предполагается, что значение типа void будет незаконным, поскольку это обычное явление, например (void)x; или вызов функции void!

Но я не могу найти, где в Стандарте говорится, что временная материализация должна быть подавлена ​​для void prvalues. Кажется, что [class.teven] / 2 говорит, что выражение с отброшенными значениями всегда материализует временное; и является ошибкой материализовать значение неполного типа. Может быть, это дефект в стандарте.


Разница в предупреждении о "неиспользованном значении", вероятно, заключается в том, что неиспользуемое значение типа void это обычное явление, и было бы не полезно предупреждать о.

Разбирается так же.

Предупреждения не приходят от парсера. Они возникают во время семантического анализа. СА заметил, что значение было создано уничтожено int(); без чтения или написания.

в void Случай, там нет значения, поэтому нет предупреждения.

Другие вопросы по тегам