前几天有人曾问过为什么有些东西会与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;
}
Run Code Online (Sandbox Code Playgroud)
使用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 = …Run Code Online (Sandbox Code Playgroud) 考虑以下程序:
#include <fstream>
struct A {};
int main(int argc, char** argv) {
A a(std::fstream(argv[1]));
}
Run Code Online (Sandbox Code Playgroud)
Clang in C++ 1y模式估计MVP被调用,因此a被解析为函数声明:
clang++ -std=c++1y -O3 -Wall -Wextra -pedantic-errors -pthread main.cpp && ./a.out
main.cpp:6:8: warning: parentheses were disambiguated as a function declaration [-Wvexing-parse]
A a(std::fstream(argv[1]));
^~~~~~~~~~~~~~~~~~~~~~~
main.cpp:6:9: note: add a pair of parentheses to declare a variable
A a(std::fstream(argv[1]));
^
( )
Run Code Online (Sandbox Code Playgroud)
我理解MVP,但不是在这个实例中:argv[1]显然是一个表达式,并且之前没有类型,所以如何将这一行解析为函数声明?
argv[1]在编译器已经选择将该行解析为函数声明之后,才会出现语义解释,它会将行消除歧义作为对象声明吗?或者它是一个Clang bug?或者通过对argv [ 1 ]我丢失的令牌的一些解释是完全正常的吗?