【问题标题】:default argument, gcc vs clang默认参数,gcc vs clang
【发布时间】:2013-08-21 05:35:04
【问题描述】:

代码如下:

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

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

VS 2013 和 gcc 4.8.0 接受这样的代码, 而 clang 3.3 拒绝这样的代码:

错误:在重新声明时添加默认参数使此构造函数成为默认构造函数

从标准(C++03 和 C++11)的角度来看,谁是正确的?

注意:

我也喜欢clang的选择,但是我要向gcc和visual studio报告bug, 如果从标准的角度来看这是不正确的,这有助于 说服编译器的开发者解决这个问题。

GCC

我在这里描述了问题:http://gcc.gnu.org/bugzilla/show_bug.cgi?id=58194

但运气不好,他们会暂停错误修复,直到草案成为标准。

【问题讨论】:

  • CLANG 更有意义。您应该将默认参数放在构造函数的声明中,而不是在其定义中。
  • 如果不查看规范,我认为 clang 是正确的。想想如果在同一个文件中没有结构定义和构造函数定义会发生什么(例如,正常拆分为头文件和源文件),那么只有具有构造函数定义的源文件才会知道默认参数和该结构没有其他用户。

标签: c++ visual-c++ gcc c++11 clang++


【解决方案1】:

这已在 Clang mailinglist 上进行了讨论,并已作为 Defect Report 核心问题 1344 提交。

来自邮件列表讨论:

这个想法是某些特殊成员的存在会影响核心 类类型的属性,例如它是 POD 还是琐碎的 可复制。决定这些属性不应该需要整个程序 知识;对我们来说,能够从中推断出它们很重要 类定义。真正有问题的案例是 通过添加默认值将“普通”构造函数转换为复制或移动构造函数 参数,但 IIRC 也引入了默认构造函数 有问题。

解决方法是您应该将默认参数放在初始 构造函数的声明。

这是 WG21 在布卢明顿会议上的最后一次讨论。来自的笔记 那里:

“共识:按照文章中的建议使这个格式不正确。核心 问题 1344。优先级 0,道格起草。”

因此,CWG(原则上)同意这应该是错误的。

TL;DR 只要缺陷得到修复,Clang 就是正确的(不确定这是否只能在 C++14 中正式发生,或者此类委员会决定是否也可以在 C++ 上追溯执行11)

【讨论】:

  • 好的,clang 就在这里。但是假设我有一个 3rd 方源代码,我非常想用 Xcode 工具链中的 clang 编译它,在我的例子中,为 iOS 各种架构构建一个带有胖库的框架。那么我在这里有什么选择呢?是否有一个标志告诉 clang 忽略此错误,或者我应该考虑以某种方式修补代码?
【解决方案2】:

我会说 CLANG 是对的。标准说(标准的旧版本和新版本都是 12.1.5):

类 X 的默认构造函数是类 X 的构造函数,可以在没有参数的情况下调用

将默认值添加到构造函数的唯一参数肯定可以在没有参数的情况下调用它,从而使其成为默认值。此外,8.3.6 说(强调我的):

默认参数表达式应在 参数声明子句 函数声明 <...>

【讨论】:

  • 您的回答绝对正确,但遵循 C++98 标准的 3.8.6.6,如果我没看错的话,可以为单个翻译单元指定更多默认参数。
  • 我看不到第二个引用的相关性。在他的示例中,默认参数表达式位于函数声明的参数声明子句中。 (该声明恰好也是一个定义,但这并不能阻止它成为一个声明。)
【解决方案3】:

你有一个声明和一个定义。在您的声明中,您没有默认值,而在您的定义中,您有默认值。事实上,声明的签名与定义的签名非常相似,但又不一样。我认为严格是个好主意,所以我认为最好强制声明与定义相同。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-02
    • 1970-01-01
    • 2021-10-27
    • 2016-01-23
    • 1970-01-01
    相关资源
    最近更新 更多