为什么在C++中使用<cstdio>而不是<stdio.h>时,"std :: printf"和"printf"都会编译?

ra1*_*ter 4 c++ namespaces header-files

据我所知,表单的标题cxyz是相同的,xyz.h唯一的区别是cxyz放置xyz.h名称空间下的所有内容std.为什么以下程序都在GCC 4.9和clang 6.0上编译?

#include <cstdio>

int main() {
    printf("Testing...");
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

和第二个程序:

#include <cstdio>

int main() {
    std::printf("Testing...");
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

FILE结构也是如此:

FILE* test = fopen("test.txt", "w");
Run Code Online (Sandbox Code Playgroud)

std::FILE* test = std::fopen("test.txt", "w");
Run Code Online (Sandbox Code Playgroud)

都工作.

到现在为止,我一直认为这是更好地使用cstdio,cstring等等,而不是他们的非命名空间的同行.但是,以上两个以上哪个程序是更好的做法?

其他C函数也是如此,例如memset(来自cstring),scanf(也来自cstdio)等.

(我知道有些人会问为什么我在C++程序中使用C IO;这里的问题不是专门的C IO,而是std::在调用命名空间C函数之前是否应该编译而没有特别指定.)

M.M*_*M.M 6

该标准允许编译器还将名称注入全局名称空间.

其中一个原因是它允许实施<cstdio>:

#include <stdio.h>

namespace std
{
    using ::printf;
    using ::fopen;
    // etc.
}
Run Code Online (Sandbox Code Playgroud)

所以编译器/库供应商不必编写和维护这么多代码.

在您自己的代码中,始终使用std::using namespace std;等等,以便您的代码可以移植到不将名称注入全局命名空间的编译器.