简体   繁体   English

默认参数,gcc vs clang

[英]default argument, gcc vs clang

Code looks like: 代码如下:

struct Foo {
    Foo(const char *);
};

Foo::Foo(const char *str = 0)
{
}

VS 2013 and gcc 4.8.0 accept such code, while clang 3.3 reject such code with: VS 2013和gcc 4.8.0接受这样的代码,而clang 3.3拒绝这样的代码:

error: addition of default argument on redeclaration makes this constructor a default constructor 错误:在重新声明时添加默认参数会使此构造函数成为默认构造函数

who is right from standard (C++03 and C++11) point of view? 谁从标准(C ++ 03和C ++ 11)的角度来看是正确的?

Note: 注意:

I like clang's choice too, but I going to report bug to gcc and visual studio, and if this is not correct from standard point of view, this helps to convince compiler's developers to fix this issue. 我也喜欢clang的选择,但我会向gcc和visual studio报告bug,如果从标准的角度来看这不正确,这有助于说服编译器的开发人员解决这个问题。

GCC GCC

I described issue here: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58194 我在这里描述了一个问题: http//gcc.gnu.org/bugzilla/show_bug.cgi?id = 58194

But no luck, they suspend bug fixing untill draft become standard. 但没有运气,他们暂停bug修复,直到草案成为标准。

This has been discussed on the Clang mailinglist and has been submitted as a Defect Report Core Issue 1344. 这已在Clang邮件列表中进行了讨论,并已作为缺陷报告核心问题1344提交。

From the mailinglist discussion: 从邮件列表讨论:

The idea is that the presence of certain special members affects core properties of a class type, like whether it's POD or trivially copyable. 这个想法是某些特殊成员的存在会影响类类型的核心属性,例如它是POD还是可以复制。 Deciding these properties should not require whole-program knowledge; 决定这些属性不应该需要整个程序知识; it's important for us to be able to deduce them just from the class definition. 能够从类定义中推断出它们对我们来说很重要。 The really problematic case is turning a "normal" constructor into a copy or move constructor by adding default arguments, but IIRC introducing a default constructor was also problematic. 真正有问题的情况是通过添加默认参数将“普通”构造函数转换为复制或移动构造函数,但IIRC引入默认构造函数也存在问题。

The fix is that you should put the default argument in the initial declaration of the constructor. 修复是您应该将默认参数放在构造函数的初始声明中。

This was last discussed by WG21 at the Bloomington meeting. 这是WG21在布卢明顿会议上讨论的最后一次。 Notes from there: 来自那里的笔记:

"Consensus: Make this ill-formed as suggested in the write-up. Core issue 1344. Priority 0, Doug drafting." “共识:按照撰写文件中的建议,使其形成不良。核心问题1344.优先级0,道格起草。”

So CWG has agreed (in principle) that this should be ill-formed. 因此,CWG(原则上)同意这应该是不正确的。

TL;DR Clang is right whenever the defect gets fixed (not sure if that can officially only happen with C++14, or if such Committee decisions can also be done retroactively on C++11) TL; DR Clang在缺陷得到修复时是正确的(不确定是否只能在C ++ 14中正式发生,或者如果委员会的决定也可以在C ++ 11上追溯完成)

I would say CLANG is right. 我会说CLANG是对的。 The standard says (12.1.5 for the both old and new versions of the standard): 标准说(标准的新旧版本均为12.1.5):

A default constructor for a class X is a constructor of class X that can be called without an argument 类X的默认构造函数是类X的构造函数,可以在没有参数的情况下调用

Adding the default value to the only argument of the constructor definitely makes it possible to call it without arguments, thus making it a default one. 将默认值添加到构造函数的唯一参数肯定可以在没有参数的情况下调用它,从而使其成为默认值。 Also, 8.3.6 says (emphasis mine): 另外,8.3.6说(强调我的):

A default argument expression shall be specified only in the parameter-declaration-clause of a function declaration <...> 默认参数表达式只能函数声明 <...>的parameter-declaration-clause中指定

You have a declaration and a definition. 你有一个声明和一个定义。 In your declaration you do not have a default value, while in your definition you have a default value. 在您的声明中,您没有默认值,而在您的定义中,您有一个默认值。 In fact the signature of the declaration is very similar to the signature of the definition, but not the same. 事实上,声明的签名与定义的签名非常相似,但不一样。 I believe that strictness is a good idea, so I believe it is better to enforce that the declaration is the same as the definition. 我认为严格是一个好主意,所以我认为最好强制声明与定义相同。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 局部专业化的默认参数[Clang是,GCC否] - Default argument for partial specialization [Clang yes, GCC no] 带有默认参数的 SFINAE 适用于 msvc 但不适用于 gcc 和 clang - SFINAE with default argument works with msvc but not with gcc and clang clang vs gcc中的空结构的默认初始化器 - Default Initializer of empty struct in clang vs gcc 在默认的初始化程序gcc vs clang中使用lambda - Using lambda in default initializer gcc vs clang clang vs gcc-空的通用lambda可变参数包 - clang vs gcc - empty generic lambda variadic argument pack constexpr函数与未使用的引用参数 - gcc vs clang - constexpr function with unused reference argument – gcc vs clang 使用函数参数作为常量表达式的一部分 - gcc vs clang - Using function argument as part of a constant expression - gcc vs clang 匿名临时和类模板参数演绎 - gcc vs clang - Anonymous temporaries and class template argument deduction - gcc vs clang Clang vs GCC - Variadic模板参数包后跟带默认值的参数适用于GCC 4.8但不适用于Clang 3.5 - Clang vs GCC - Variadic template parameter pack followed by parameter with default value works in GCC 4.8 but not Clang 3.5 引用这个指针:GCC vs clang - Reference to the this pointer: GCC vs clang
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM