Kae*_*Rin 14 c++ language-lawyer auto c++14
我的问题与此类似,但略有不同。
假设我有两个翻译单元,exec.cpp和lib.cpp,如下:
// exec.cpp
int foo();
int main() {
return foo();
}
Run Code Online (Sandbox Code Playgroud)
和
// lib.cpp
auto foo() {
return 42;
}
Run Code Online (Sandbox Code Playgroud)
将它们编译和链接在一起是否合法?还是格式错误的 NDR?
注意:g++ 和 clang 都使用命令生成预期的可执行文件(即返回 42) <compiler> exec.cpp lib.cpp -o program
注意:可以说这是一个不好的做法(因为如果实现发生变化,返回类型可能会改变,并破坏代码)。但我还是想知道答案。
以下所有标准参考均指N4861:2020 年 3 月后布拉格工作草案/C++20 DIS。.
来自[basic.link]/11 [强调我的]:
在所有类型调整后(在此期间,typedef 被它们的定义替换),所有引用给定变量或函数的声明指定的类型应该是相同的,除了数组对象的声明可以指定不同的数组类型缺少主数组绑定([dcl.array])。在类型标识上违反此规则不需要诊断。
[dcl.spec.auto]/3涵盖了占位符类型可以与函数声明符一起出现,并且如果此声明符不包含尾随返回类型(就像 OP 的示例一样)
[...] 否则 [无尾随返回类型],函数声明器应声明一个函数。
在哪里
[...] 函数的返回类型是从函数
return体 ([stmt.if]) 中的非丢弃语句(如果有)推导出来的。
[dcl.fct]/1涵盖了不包含尾随返回类型的函数声明符[强调我的,删除在此特定示例中不适用的语法的opt部分]:
在声明
T D,其中D的形式为[...]的类型说明符-ID中D是“衍生的说明符类型列表的功能参数类型列表返回T” [...]
因此,两个声明
int f(); // #1
auto foo() { // #2
// [dcl.spec.auto]/3:
// return type deduced to 'int'
}
Run Code Online (Sandbox Code Playgroud)
两个声明函数,其中相关联的类型说明符-ID在D这些的T D声明是
“返回参数类型列表的派生声明符类型列表函数”
T
在这两种情况下,T是int:
#1,#2。因此,声明#1和#2,经过所有类型的调整,具有相同的(函数)类型,从而满足 [basic.link]/11,并且 OP 的示例格式良好。auto f()然而,对 的定义的任何轻微变化都可能导致推导出的返回类型不是int,在这种情况下,[basic.link]/11 被违反,NDR。