是否允许在一个翻译单元中使用显式 return 类型并在另一个翻译单元中推导 return 类型?
Is using explicit return type in one translation unit and deduced return type in another allowed?
我的问题与 this one 相似,但略有不同。
假设我有两个翻译单元,exec.cpp
和lib.cpp
,如下:
// exec.cpp
int foo();
int main() {
return foo();
}
和
// lib.cpp
auto foo() {
return 42;
}
编译和 link 它们一起合法吗?还是格式错误的 NDR?
注意:g++ 和 clang 都会使用命令 <compiler> exec.cpp lib.cpp -o program
生成预期的可执行文件(即 returns 42)
注意:可以说这是一种不好的做法(因为 return 类型可以在实现更改时更改,并破坏代码)。但是我还是很想知道答案。
以下所有标准参考均指N4861: March 2020 post-Prague working draft/C++20 DIS.。
来自 [basic.link]/11 [强调 我的]:
After all adjustments of types (during which typedefs are replaced by their definitions), the types specified by all declarations referring to a given variable or function shall be identical, except that declarations for an array object can specify array types that differ by the presence or absence of a major array bound ([dcl.array]). A violation of this rule on type identity does not require a diagnostic.
[dcl.spec.auto]/3 涵盖占位符类型可以与函数声明符一起出现,并且如果该声明符不包含 trailing-return-type (就像OP的例子一样)
[...] Otherwise [no trailing-return-type], the function declarator shall declare a function.
哪里
[...] the return type of the function is deduced from non-discarded return
statements, if any, in the body of the function ([stmt.if]).
[dcl.fct]/1 涵盖不包含 trailing-return-type [emphasis mine 的函数声明符, 删除不适用于此特定示例的 opt 部分语法]:
In a declaration T D
where D
has the form [...] the type of the declarator-id in D
is “derived-declarator-type-list function of parameter-type-list returning T
” [...]
因此,两个声明
int f(); // #1
auto foo() { // #2
// [dcl.spec.auto]/3:
// return type deduced to 'int'
}
两者都声明函数,其中 T D
声明中的 D
中关联的 declarator-id 的类型是
“derived-declarator-type-list function of parameter-type-list returning T
”
在这两种情况下,T
是 int
:
- 在
#1
、 中明确指定
- 根据
#2
中的 [dcl.spec.auto]/3 推导。
因此,声明 #1
和 #2
,在所有类型调整之后,具有相同的(函数)类型,从而满足 [basic.link]/11,以及 OP 的示例是良构的。然而,auto f()
定义的任何细微变化都可能导致推导的 return 类型不是 int
,在这种情况下 [basic.link]/11 被违反, NDR.
我的问题与 this one 相似,但略有不同。
假设我有两个翻译单元,exec.cpp
和lib.cpp
,如下:
// exec.cpp
int foo();
int main() {
return foo();
}
和
// lib.cpp
auto foo() {
return 42;
}
编译和 link 它们一起合法吗?还是格式错误的 NDR?
注意:g++ 和 clang 都会使用命令 <compiler> exec.cpp lib.cpp -o program
注意:可以说这是一种不好的做法(因为 return 类型可以在实现更改时更改,并破坏代码)。但是我还是很想知道答案。
以下所有标准参考均指N4861: March 2020 post-Prague working draft/C++20 DIS.。
来自 [basic.link]/11 [强调 我的]:
After all adjustments of types (during which typedefs are replaced by their definitions), the types specified by all declarations referring to a given variable or function shall be identical, except that declarations for an array object can specify array types that differ by the presence or absence of a major array bound ([dcl.array]). A violation of this rule on type identity does not require a diagnostic.
[dcl.spec.auto]/3 涵盖占位符类型可以与函数声明符一起出现,并且如果该声明符不包含 trailing-return-type (就像OP的例子一样)
[...] Otherwise [no trailing-return-type], the function declarator shall declare a function.
哪里
[...] the return type of the function is deduced from non-discarded
return
statements, if any, in the body of the function ([stmt.if]).
[dcl.fct]/1 涵盖不包含 trailing-return-type [emphasis mine 的函数声明符, 删除不适用于此特定示例的 opt 部分语法]:
In a declaration
T D
whereD
has the form [...] the type of the declarator-id inD
is “derived-declarator-type-list function of parameter-type-list returningT
” [...]
因此,两个声明
int f(); // #1
auto foo() { // #2
// [dcl.spec.auto]/3:
// return type deduced to 'int'
}
两者都声明函数,其中 T D
声明中的 D
中关联的 declarator-id 的类型是
“derived-declarator-type-list function of parameter-type-list returning
T
”
在这两种情况下,T
是 int
:
- 在
#1
、 中明确指定
- 根据
#2
中的 [dcl.spec.auto]/3 推导。
因此,声明 #1
和 #2
,在所有类型调整之后,具有相同的(函数)类型,从而满足 [basic.link]/11,以及 OP 的示例是良构的。然而,auto f()
定义的任何细微变化都可能导致推导的 return 类型不是 int
,在这种情况下 [basic.link]/11 被违反, NDR.