【问题标题】:Why do both "std::printf" and "printf" compile when using <cstdio> rather than <stdio.h> in C++? [duplicate]为什么在 C++ 中使用 <cstdio> 而不是 <stdio.h> 时“std::printf”和“printf”都编译? [复制]
【发布时间】:2015-03-29 09:42:18
【问题描述】:

据我所知,cxyz 形式的标题与xyz.h 相同,唯一的区别是cxyzxyz.h 的所有内容放在命名空间std 下。为什么下面的程序都在 GCC 4.9 和 clang 6.0 上编译?

#include <cstdio>

int main() {
    printf("Testing...");
    return 0;
}

和第二个程序:

#include <cstdio>

int main() {
    std::printf("Testing...");
    return 0;
}

FILE 结构也是如此:

FILE* test = fopen("test.txt", "w");

std::FILE* test = std::fopen("test.txt", "w");

两者都有效。

到目前为止,我一直认为最好使用cstdiocstring 等,而不是它们的非命名空间对应物。但是,以上两个程序中哪个是更好的做法?

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

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

【问题讨论】:

  • 我明白了。因此,在我的代码中,如果我希望使用例如来自 cstring 标头的 memset,我应该使用哪种样式?写'std :: memset'还是'memset''更好

标签: c++ namespaces header-files


【解决方案1】:

该标准允许编译器也将名称注入全局命名空间。

这样做的一个原因是它允许&lt;cstdio&gt; 的实现是:

#include <stdio.h>

namespace std
{
    using ::printf;
    using ::fopen;
    // etc.
}

因此编译器/库供应商不必编写和维护这么多代码。

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

【讨论】:

  • 感谢您的解释!这有点令人困惑,因为我还没有看到不将名称注入全局命名空间的编译器。
  • @Ra1nMaster 他们这样做可能是为了避免那些想知道为什么printf 不起作用的人的错误报告/支持问题
  • @ra1nmaster:严格来说,负责将函数注入(或不注入)全局命名空间的是标准库,而不是编译器。
  • @rici 标准库的存在是编译器的实现细节
猜你喜欢
  • 2010-09-25
  • 1970-01-01
  • 2014-02-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-06
  • 2013-01-23
  • 1970-01-01
相关资源
最近更新 更多