程序在 3 个主要 C++ 编译器中的编译方式不同。哪一个是对的?
Program being compiled differently in 3 major C++ compilers. Which one is right?
作为我之前问题的一个有趣的跟进(虽然没有太大的实际意义):
我发现将括号中的声明与 injected class name 功能结合使用可能会导致有关编译器行为的令人惊讶的结果。
看看下面的程序:
#include <iostream>
struct B
{
};
struct C
{
C (){ std::cout << "C" << '\n'; }
C (B *) { std::cout << "C (B *)" << '\n';}
};
B *y = nullptr;
int main()
{
C::C (y);
}
使用 g++ 4.9.2 编译时出现以下编译错误:
main.cpp:16:10: error: cannot call constructor 'C::C' directly [-fpermissive]
用MSVC2013/2015编译成功并打印C (B *)
它使用 clang 3.5 编译成功并打印 C
所以必问的问题是哪一个是正确的? :)
(虽然我强烈倾向于 clang 版本,而 msvc 停止声明变量的方式只是在技术上使用其 typedef 更改类型后似乎有点奇怪)
G++ 是正确的,因为它给出了一个错误。因为没有 new
运算符,无法以这种格式直接调用构造函数。尽管您的代码调用了 C::C
,但它看起来像是构造函数调用。但是,根据C++11标准3.4.3.1,这不是合法的函数调用,也不是类型名().
Clang 是错误的,因为它甚至没有调用正确的函数。
MSVC 是合理的,但仍然不符合标准。
GCC 是正确的,至少根据 C++11 查找规则。 3.4.3.1 [class.qual]/2 指定,如果嵌套名称说明符与 class 名称相同,则它指的是构造函数而不是注入的 class 名称。它给出了示例:
B::A ba; // object of type A
A::A a; // error, A::A is not a type name
struct A::A a2; // object of type A
看起来 MSVC 将其误解为函数样式的强制转换表达式,它创建了一个临时的 C
并将 y
作为构造函数参数;并且 Clang 将其误解为类型为 C
.
的名为 y
的变量的声明
作为我之前问题的一个有趣的跟进(虽然没有太大的实际意义):
我发现将括号中的声明与 injected class name 功能结合使用可能会导致有关编译器行为的令人惊讶的结果。
看看下面的程序:
#include <iostream>
struct B
{
};
struct C
{
C (){ std::cout << "C" << '\n'; }
C (B *) { std::cout << "C (B *)" << '\n';}
};
B *y = nullptr;
int main()
{
C::C (y);
}
使用 g++ 4.9.2 编译时出现以下编译错误:
main.cpp:16:10: error: cannot call constructor 'C::C' directly [-fpermissive]
用MSVC2013/2015编译成功并打印
C (B *)
它使用 clang 3.5 编译成功并打印
C
所以必问的问题是哪一个是正确的? :)
(虽然我强烈倾向于 clang 版本,而 msvc 停止声明变量的方式只是在技术上使用其 typedef 更改类型后似乎有点奇怪)
G++ 是正确的,因为它给出了一个错误。因为没有 new
运算符,无法以这种格式直接调用构造函数。尽管您的代码调用了 C::C
,但它看起来像是构造函数调用。但是,根据C++11标准3.4.3.1,这不是合法的函数调用,也不是类型名(
Clang 是错误的,因为它甚至没有调用正确的函数。
MSVC 是合理的,但仍然不符合标准。
GCC 是正确的,至少根据 C++11 查找规则。 3.4.3.1 [class.qual]/2 指定,如果嵌套名称说明符与 class 名称相同,则它指的是构造函数而不是注入的 class 名称。它给出了示例:
B::A ba; // object of type A
A::A a; // error, A::A is not a type name
struct A::A a2; // object of type A
看起来 MSVC 将其误解为函数样式的强制转换表达式,它创建了一个临时的 C
并将 y
作为构造函数参数;并且 Clang 将其误解为类型为 C
.
y
的变量的声明