Разница между разбором 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
Случай, там нет значения, поэтому нет предупреждения.