Кто-то на днях спросил, почему что-то компилируется с clang, но не с gcc. Я интуитивно понимал, что происходит, и мог помочь человеку, но это заставило меня задуматься - согласно стандарту, какой компилятор был правильным? Вот упрощенная версия кода:
#include <iostream>
#include <string>
class foo
{
public:
foo(const std::string& x):
name(x)
{ }
foo& operator()(const std::string& x)
{
std::cout << name << ": " << x << std::endl;
return (*this);
}
std::string name;
};
int main()
{
std::string x = "foo";
foo(x)("bar")("baz");
return 0;
}
Это нормально компилируется с clang ++, но g ++ дает следующую ошибку:
runme.cpp: In function ‘int main()’:
runme.cpp:21:11: error: conflicting declaration ‘foo x’
foo(x)("bar")("baz");
^
runme.cpp:20:17: error: ‘x’ has a previous declaration as ‘std::string x’
std::string x = "foo";
Если я добавлю пару скобок в строку 21, g ++ будет счастлив:
(foo(x))("bar")("baz");
Другими словами, g ++ интерпретирует эту строку как:
foo x ("bar")("baz");
Мне кажется, это ошибка в g ++, но опять же, я хотел спросить стандартных экспертов, какой компилятор ошибся?
PS: gcc-4.8.3, clang-3.5.1
1 ответ
Если убрать строчку
std::string x = "foo";
То g ++ жалуется на:
foo(x)("bar")("baz");
С синтаксической ошибкой:
foo.cc:20:18: error: expected ',' or ';' before '(' token
foo(x)("bar")("baz");
Я не понимаю, как foo (x)("bar")("baz");
может быть допустимым объявлением, и, очевидно, g ++ тоже не может. Строка foo x("bar")("baz");
отклоняется с той же ошибкой.
«Разрешение двусмысленности», упомянутое в сообщении Шафика, срабатывает только тогда, когда выражение-выражение синтаксически неотличимо от объявления. Однако в этом случае это недопустимый синтаксис объявления, поэтому нет двусмысленности, это должен быть оператор-выражение.
G ++ не может обработать строку как выражение-оператор, поэтому это ошибка g ++.
Это очень похоже на эту ошибку g ++. недавно обсуждался на SO; кажется, что g ++ слишком рано решает при обработке, что строка должна быть объявлением.
Похожие вопросы
Связанные вопросы
Новые вопросы
c++
C++ — это язык программирования общего назначения. Изначально он разрабатывался как расширение C и имел аналогичный синтаксис, но теперь это совершенно другой язык. Используйте этот тег для вопросов о коде, который будет скомпилирован с помощью компилятора C++. Используйте тег версии для вопросов, связанных с конкретной стандартной версией [C++11], [C++14], [C++17], [C++20] или [C++23]. и т.д.