前向声明函数允许不正确的返回类型:为什么这里没有链接器错误?

问题描述 投票:0回答:1
$ g++ --version
Configured with: --prefix=/Library/Developer/CommandLineTools/usr --with-gxx-include-dir=/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/c++/4.2.1
Apple clang version 12.0.0 (clang-1200.0.32.29)
Target: x86_64-apple-darwin23.4.0
Thread model: posix
InstalledDir: /Library/Developer/CommandLineTools/usr/bin

a.cc

$ cat a.cc
#include<iostream>

using namespace std;

static int x = 5053;

void f2();

int main() {
  cout << "a: " << x << endl;
  f2();
  return 0;
}

b.cc

$ cat b.cc
#include<iostream>

using namespace std;

static int x = 4921;

string f2() {
  cout << "b: " << x << endl;
  return "";
}

./a.out

$ g++ --std=c++17 a.cc b.cc && ./a.out
a: 5053
b: 4921

为什么我能够将

string f2();
中的
b.cc
转发为
void f2();
中的
a.cc

任何对允许这样做的 cppreference 或规范的引用将不胜感激。

c++ return-type forward-declaration
1个回答
0
投票

任何对允许这样做的 cppreference 或规范的引用将不胜感激。

该程序有未定义的行为,因为您已经odr使用过

f2
,但没有为
void f2();
版本提供任何定义。基本上,我们需要为 odr 使用的非内联函数提供一个且仅有一个定义。

这可以从ODR看出:

在整个程序中(包括任何标准库和用户定义库)中需要出现 odr 使用的每个非内联函数或变量(见下文)的且只有一个定义。编译器不需要诊断此违规,但违反它的程序的行为是未定义的

这似乎是一个 apple clang bug,因为 main 中的调用

f2()
选择了未定义(未实现)的
void f2()
版本,因此我们应该得到一个链接器错误。


请注意,我们确实遇到了 clang 和 gcc 的链接器错误。 演示。所以这似乎是 apple clang 特有的错误。

© www.soinside.com 2019 - 2024. All rights reserved.