首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >程序在3个主要的C++编译器中以不同的方式编译。哪一个是对的?

问程序在3个主要的C++编译器中以不同的方式编译。哪一个是对的?
EN

Stack Overflow用户
提问于 2015-04-17 01:01:25
回答 2查看 4.9K关注 0票数 117

作为我上一个问题的一个有趣的后续(虽然没有很大的实际意义):Why does C++ allow us to surround the variable name in parentheses when declaring a variable?

我发现将括号中的声明与injected class name特性相结合可能会导致有关编译器行为的令人惊讶的结果。

看看下面的程序:

代码语言:javascript
复制
#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进行

  1. 编译时出现以下编译错误:

-fpermissive

  • It :错误:无法直接调用构造函数'C::C‘-fpermissive

  • It使用MSVC2013/2015成功编译并打印C (B *)

  • It使用clang3.5成功编译并打印C

所以必须问的问题是哪一个是正确的?:)

(我强烈倾向于clang版本和msvc的方式来停止声明变量,只是在技术上改变了它的typedef的类型,这看起来有点奇怪)

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-04-17 01:17:35

至少根据C++11查找规则,GCC是正确的。3.4.3.1 class.qual/2指定,如果嵌套名称说明符与类名相同,它引用的是构造函数,而不是注入的类名。它给出了示例:

代码语言:javascript
复制
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错误地将其解释为函数样式的强制转换表达式,创建了一个以y作为构造函数参数的临时C;而Clang错误地将其解释为C类型的名为y的变量的声明。

票数 91
EN

Stack Overflow用户

发布于 2015-04-17 01:14:37

G++是正确的,因为它给出了错误。因为构造函数不能在没有new运算符的情况下以这种格式直接调用。尽管您的代码调用了C::C,但它看起来像是一个构造函数调用。但是,根据C++11标准3.4.3.1,这不是合法的函数调用,也不是类型名(see Mike Seymour's answer)。

Clang是错误的,因为它甚至没有调用正确的函数。

MSVC是合理的,但它仍然不遵循标准。

票数 16
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29681449

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档