停止由 C++ 引起的 <stdio.h> 定义的误捕包括

Stop bycatch of <stdio.h> definitions caused by C++ includes

在对 , I was shown a code example 的评论中似乎使用了 printfputs 而没有包含 <stdio.h> 但在线编译器没有抱怨。[ 1] 为了了解发生了什么,我将它复制到本地 IDE。

还原成相关的include和output,基本上就是这样:

#include <string>
#include <map>
#include <optional>

int main() {
  printf("Answer %d\n", 42);
  puts("Question?");
}

使用 gcc 8.1.0(与 Clode::Blocks 20.03 一起打包)进行实验,我发现包含可以进一步减少到

还有一个示例测试 - C++14 (gcc 8.3) - on ideone.com 编译并运行良好:

#include <iostream>

int main() {
    printf("printf without #include <stdio.h>\n");
    return 0;
}

<stdio.h> 中的其他定义也是如此,例如 FILE

我在 cppreference.com

找不到任何信息

我也尝试了几个网络和 SO 搜索,但到目前为止没有成功。

虽然可能对于小示例免费获得一些强大的功能很方便,但一个严肃的项目可能会受到影响:除了相对容易修复编译器错误之外,我明白了严重运行时错误的危险。

怎样才能有效control/prevent这种包容?


[1] 引用的代码现在包含 include 语句,但我很确定它在我复制它的阶段没有..或者我只是复制了一部分? ...无论如何,观察到的行为如上所述。

恐怕你不能。

标准要求众所周知的包含文件声明相关名称,但不阻止它们包含其他 files/names,如果库实现发现它有用的话。

换句话说,在包含 iostream 之后,您确定属于它的所有名称都已正确声明,但您无法知道(除非检查文件本身)是否定义了其他名称,或者是否其他标准文件已包含在内。在这里,您的实现选择自动包含 stdio.h,但不同的(标准库)实现可以选择不包含它。您已进入未指定...

的世界

除了关于“纯度”的任何争论之外,我看不出包含这些函数的声明有何危害。事实上, 没有 并让编译器隐含地假设 int printf()——尽管只有 C 编译器会这样做,C++ 不会——这是在自找麻烦。

printf 是 C 语言标准的一部分。尽管 C++ 不是 C,但它们的生态系统之间有太多重叠,以至于 C++ 也将 printf 视为实现运行时环境的一部分,就像它与 C 标准库中的所有其他函数一样。

因此,所有这些符号都是保留的。除了实际实现运行时库本身之外,您没有必要自己定义这些名称的符号。

#include 预处理器指令只是内联文本替换,其中文本是从其他文件中提取的。

(extern) symbol declarations 不会创建这些名称的符号,但它们会确保您不会 自己重新定义这些符号。

所以我真的不明白你对运行时错误的担忧从何而来。