【问题标题】:Is function parameter constness mismatch allowed?是否允许函数参数常量不匹配?
【发布时间】:2016-04-10 16:55:56
【问题描述】:

关于using const function parameters 我听说在某些 OS X 系统上,参数的常量性被破坏到函数签名中。例如,如果在接口头文件中有以下声明:

int f(int argument);

但如果只实现这个功能:

int f(int const argument);

那么这可能会导致 OS X(但不是 Linux)上的链接失败,因为 OS X 破坏 C++ 函数签名的方式包括参数的常量性。

正确的修饰行为是什么? C++ 标准对此有发言权吗?

【问题讨论】:

  • int f(int const argument); 是相当多余的,但如果你坚持它是有意义的。
  • 出于兴趣,您从哪里听到的?如果属实,这将是非常糟糕的。
  • 正确的行为是忽略顶级const,这意味着const适用于参数本身(而不是参数所指的东西)。例如,int *const 和 int * 相同,但 int const * 和 int * 不同。很难相信 OS X 会有一个编译器会出错(这是 C++ 的一个非常基本的部分,早在 OS X 出现之前就已经广为人知了)。
  • @OliverCharlesworth 大约 2 年前,一些同事注意到一些代码由于这种不匹配而无法在 OS X 上链接,因此从那以后我一直试图避免这种情况。我不记得他们使用了什么工具链。
  • @jotik 这听起来不太可能。你能重现它吗?

标签: c++ macos abi name-mangling


【解决方案1】:

出于名称修改的目的,应忽略顶级 const 和 volatile 限定符。这可以从标准中的两件事来确定。首先,函数的签名用于名称修改。

在 C++14 标准中,1.3.17 节定义了一个签名:

名称、参数类型列表 (8.3.5) 和封闭的命名空间(如果有)[ 注意:签名用作名称修改和链接的基础。 ——尾注]

要获取参数类型列表的定义,我们接着参考第8.3.5/5节:

函数的类型使用以下规则确定。每个参数的类型 (包括函数参数包)由它自己的 decl-specifier-seq 和 declarator 确定。后 确定每个参数的类型,任何类型为“T 数组”或“函数返回 T”的参数是 分别调整为“指向 T 的指针”或“指向返回 T 的函数的指针”。制作清单后 在参数类型中,任何修改参数类型的顶级 cv 限定符在形成 函数类型。转换后的参数类型的结果列表以及省略号的存在与否 或者函数参数包是函数的parameter-type-list。 [注:此转换不 影响参数的类型。例如 int()(const int p, decltype(p)) 和 int()(int, const int) 是相同的类型。 ——尾注]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-04-20
    • 2019-12-05
    • 2012-12-07
    • 1970-01-01
    • 2017-06-30
    • 1970-01-01
    相关资源
    最近更新 更多