为什么在包含 iostream 时可以使用 printf()?

Why can I use printf() when including iostream?

即使使用 C++11 标准下的 minGW 编译器,这段代码也能正常工作:

#include <iostream>

int main(int argc, char const *argv[])
{
    printf("haha");
    return 0;
}

为什么要这样做?我没有包含 stdio.h,但我可以使用 printf()rand() 等函数。它们是否包含在 iostream 中?至少我没有发现它们包括在内。如果你说它包含在 iostream 中,请给我证据。

它是否有效由实现定义。

实施可能包括它需要的额外 header,但作为开发人员,您不应该依赖它并包括 cstdio,这是访问 [=14= 的保证方式].

包括 stdio.hprintf 放入全局命名空间中,这通常不是人们在 C++ 中想要的,所以坚持使用 cstdio

您的实现似乎将 printf 放入了全局命名空间,即使您只包含了一个 C++ header。这很不幸,但这种情况也会发生。


证据:我的预处理器名为 cpp,我可以用它来列出包含的 header 文件。我有这个程序,我称之为 std.cpp:

#include <iostream>
int main() {}

如果我使用 cpp 列出包含的 headers

的一小部分
cpp -M std.cpp | tr -d '\' | tr ' ' '\n' | \
grep -E '^/[^\.]+$' | awk -F/ '{print $NF}'

我得到这些 C++ headers 在我的系统上:

iostream
ostream
ios
iosfwd
cwchar
exception
typeinfo
new
type_traits
cstdint
clocale
cctype
string
initializer_list
cstdlib
cstdio
cerrno
system_error
stdexcept
streambuf
cwctype
istream

是的,cstdio 在那里,其中还包括 stdio.h

一样,通常包含<cstdio><cstdlib>也是如此。

我的 <iostream> 头文件包括:

#include <bits/c++config.h>

其中包括:

/* Define if C99 functions or macros in <stdio.h> should be imported in
<cstdio> in namespace std for C++11. */
#define _GLIBCXX11_USE_C99_STDIO 1

/* Define if C99 functions or macros in <stdio.h> should be imported in
<cstdio> in namespace std for C++98. */
#define _GLIBCXX98_USE_C99_STDIO 1

<stdlib.h>也一样。

实施信息:

Thread model: posix
gcc version 9.2.0 (tdm64-1) 

您可以打开包含文件并查看以下包含链: iostream => istream => ostream => ios => xlocknum => cstdio

cstdiostdio.h

的 C++ 包装器

所有突出显示的名称都是标准的 headers,ioscstdio 之间的链是 compiler-dependent(在我的例子中 xlocknum 是 VS2017 编译器的内部)