C++ 是否允许在一个转换单元中使用显式返回类型,在另一个转换单元中使用推断返回类型?

C++ 是否允许在一个转换单元中使用显式返回类型,在另一个转换单元中使用推断返回类型?,c++,c++14,language-lawyer,auto,C++,C++14,Language Lawyer,Auto,我的问题类似于,但有细微的不同 假设我有两个翻译单元,exec.cpp和lib.cpp,如下所示: //exec.cpp int foo(); int main(){ 返回foo(); } 及 //lib.cpp 自动foo(){ 返回42; } 编辑并将它们链接在一起是否合法?还是形式不正确的NDR 注意:g++和clang都使用命令exec.cpp lib.cpp-o程序生成预期的可执行文件(即返回42) 注意:可以说这是一种不好的做法(因为如果实现发生更改,返回类型可能会更改,并破坏代

我的问题类似于,但有细微的不同

假设我有两个翻译单元,
exec.cpp
lib.cpp
,如下所示:

//exec.cpp
int foo();
int main(){
返回foo();
}

//lib.cpp
自动foo(){
返回42;
}
编辑并将它们链接在一起是否合法?还是形式不正确的NDR

注意:g++和clang都使用命令exec.cpp lib.cpp-o程序生成预期的可执行文件(即返回42)

注意:可以说这是一种不好的做法(因为如果实现发生更改,返回类型可能会更改,并破坏代码)。但我仍然想知道答案。

以下所有标准参考文献均指


从[强调我的]:

对类型进行所有调整后(在此期间,typedef被其定义所取代),引用给定变量或函数的所有声明所指定的类型应相同,除了数组对象的声明可以指定数组类型,这些类型因是否存在主数组绑定([dcl.array])而不同。对类型标识违反此规则不需要诊断

介绍占位符类型可以与函数声明符一起出现,以及如果此声明符不包含尾部返回类型(如OP示例所示)

[…]否则[无尾随返回类型],函数声明符应声明函数

在哪里

[…]函数的返回类型是从函数体([stmt.if])中未丢弃的
return
语句(如果有)推导出来的

涵盖不包含尾随返回类型的函数声明符[emphasismine,删除语法中不适用于此特定示例的opt部分]:

在声明
td
中,其中
D
的形式为[…]
D
中声明符id的类型为
“参数类型列表的派生声明符类型列表函数返回
T
”[…]

因此,这两项声明

int f();      // #1
auto foo() {  // #2
    // [dcl.spec.auto]/3:
    // return type deduced to 'int'
}
这两个声明函数的
D
声明中关联的声明器id的类型为

“参数类型列表的派生声明器类型列表函数返回
T

在这两种情况下,
T
都是
int

  • #1
    中明确规定
  • 根据
    #2
    中的[dcl.spec.auto]/3推导

因此,在所有类型调整之后,声明
#1
#2
具有相同的(函数)类型,从而实现了[basic.link]/11,OP的示例格式良好。但是,对
auto f()
定义的任何细微变化都可能导致推导出的返回类型不是
int
,在这种情况下,违反了[basic.link]/11,NDR。

即使它不是非法的,从长远来看,它也会导致难以调试的细微问题,从而耗费您的时间。为什么要冒险呢?不要在评论中回答,people@LanguageLawyer不是这样。只有一个定义。但另一个翻译单位中的德尔卡特是否包括“重新表述”?至少在你的情况下不是这样。我希望在这里成为控制规则,但我不认为在这种情况下如何解释“同一类型”是特别清楚的。