为什么在包含 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.h
将 printf
放入全局命名空间中,这通常不是人们在 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
cstdio 是 stdio.h
的 C++ 包装器
所有突出显示的名称都是标准的 headers,ios 和 cstdio 之间的链是 compiler-dependent(在我的例子中 xlocknum 是 VS2017 编译器的内部)
即使使用 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.h
将 printf
放入全局命名空间中,这通常不是人们在 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
cstdio 是 stdio.h
的 C++ 包装器所有突出显示的名称都是标准的 headers,ios 和 cstdio 之间的链是 compiler-dependent(在我的例子中 xlocknum 是 VS2017 编译器的内部)