Я, конечно, что-то упускаю, но я не понимаю, почему это компилируется (как с g ++, так и clang ++):
struct A
{
};
struct B
{
};
int main()
{
A a(B);
}
Прежде всего, B
это тип ... не значение. Как я должен интерпретировать этот код?
c++
syntax
declaration
most-vexing-parse
Пикауд Винсент
источник
источник
A a(B());
может быть определение переменной или объявление функции.struct A{}; int main() { A(foo); }
компилируется как есть , даже еслиfoo
ничего не называется.Ответы:
Это интерпретируется как объявление именованной функции
a
, которая принимает один аргумент типаB
и возвращаетA
.источник
A a{B};
Это просто объявление функции, объявляющее
a
функцию, возвращающуюA
и принимающую один безымянный параметр типаB
.Это допустимо, потому что объявления функций в отличие от определений функций допускаются в определениях функций.
источник
Эта проблема известна как самый неприятный анализ . Строка
A a(B);
может быть интерпретирована как объявление функции с именем,a
возвращающей объект типаA
и принимающей безымянный параметр типаB
.Одним из способов избежать этой проблемы является использование единого синтаксиса инициализации, который был введен в C ++ 11, который состоит в использовании фигурных скобок вместо скобок:
A a{B};
возвращает ошибку. Строка теперь интерпретируется как объявление переменнойB
, которая инициализируется с помощью типа, а не значения.Вот больше информации:
Самый неприятный парсинг: как это быстро определить и исправить
источник
struct A { };
недопустимы в стандартном C, даже если некоторые компиляторы разрешают их. Снимите скобки, и там не будет проблем. Кроме того, в C декларирование или определениеstruct A
не создает имя типаA
(вы должны префиксировать егоstruct
или добавитьtypedef struct A A;
куда-либо, прежде чемA
использовать безstruct
префикса). Кроме того, в C нет альтернативного синтаксического анализа объявления функции - использованиеtype name(...);
просто не может быть определением переменной; это всегда объявление функции (или недействительное). Код в вопросе недействителен в C.