在C++中使用C头时,我们应该使用std ::或全局命名空间中的函数吗?

Dei*_*Dei 106 c++ std language-lawyer

C在某种程度上并不完全是C++的一个子集.因此,我们可以通过更改名称(stdio.hto cstdio,stdlib.hto cstdlib)来使用C++中的大多数C函数/头文件.

我的问题实际上是一种语义.在C++代码(使用GCC编译器的最新版本),我可以打电话printf("Hello world!");,并std::printf("Hello world!");和它的工作原理完全一样.在我使用它的参考中也显示为std::printf("Hello world!");.

我的问题是,它是否更适合std::printf();在C++中使用?有区别吗?

ser*_*gej 102

从C++ 11标准(强调我的):

D.5 C标准库头文件[depr.c.headers]

  1. 为了与C标准库兼容......
  2. 每个C头(每个头都具有name.h形式的名称)的行为就好像每个由相应的cname头放置在标准库命名空间中的名称放在全局命名空间范围内.这是未指定的这些名字是否首次宣布或命名空间范围内定义(3.3.6)命名空间性病,然后通过使用明确的-声明(7.3.3)注入到全局命名空间范围.
  3. 示例:标头<cstdlib> 确实在命名空间中 std提供其声明和定义.它还可以在全局命名空间中提供这些名称.标题<stdlib.h> 肯定在全局命名空间中提供相同的声明和定义,就像在C标准中一样.它还可以在命名空间中提供这些名称std.

不推荐使用«name.h»标头,它们已被确定为从未来版本中删除的候选者.

因此,我建议包含«cname»标头并使用std命名空间中的声明和定义.

如果由于某些原因必须使用«name.h»头文件(不推荐使用,请参见上文),我建议使用全局命名空间中的声明和定义.

换句话说:更喜欢

#include <cstdio>

int main() {
    std::printf("Hello world\n");
}
Run Code Online (Sandbox Code Playgroud)

过度

#include <stdio.h>

int main() {
    printf("Hello world\n");
}
Run Code Online (Sandbox Code Playgroud)

  • <name.h>可能已弃用,很可能不会很快被删除.事实恰恰相反.有人建议删除已弃用的标签,请参阅http://open-std.org/JTC1/SC22/WG21/docs/papers/2017/p0619r0.html#3.5.*"最后,很明显C标题将永远保留,作为与C和POSIX的重要兼容层.可能值得取消对标题的解除,[..]"* (4认同)
  • 另见Jonathan Wakely的[为什么<cstdlib>比你想象的更复杂](https://developers.redhat.com/blog/2016/02/29/why-cstdlib-is-more-complicated-than-you-可能 - 想想/)来自红帽博客.他从C++标准库实现者的角度详述了许多问题.他还提供了回溯到C++ 98的历史. (3认同)
  • @Sjoerd 有趣。更新提案:&lt;http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p2139r1.html#3.9&gt; (2认同)

T.C*_*.C. 78

<cmeow>始终提供::std::purr,可能会或可能不会提供::purr.

<meow.h>始终提供::purr,可能会或可能不会提供::std::purr.

使用保证由您包含的标题提供的表单.

  • STL伪装得不好? (7认同)
  • @TC如果只有发明Foo和Bar的人和你一样有创造力... (2认同)
  • @LF您可能需要`strcat`来生成`:: purr`。 (2认同)

jal*_*alf 7

不,你也没关系.

最初的目的就是让这个<___.h>标题会是这把一切都放在全局命名空间中的C版本和<c___>标题将是C++ -指明分数的版本,这一切都发生在std命名空间.

但实际上,C++版本还将所有内容都放入了全局命名空间.并且没有明确的共识认为使用这些std::版本是"正确的事情".

所以基本上,使用你喜欢的任何一个.最常见的可能是在全局命名空间中使用C标准库函数(printf而不是std::printf),但没有太多理由认为一个"更好"而不是另一个.

  • @JeremyFriesner你在SO上发帖,看看你是否有不同意见.:) (8认同)
  • 如何客观地确定是否已达成共识? (3认同)
  • "并且没有明确的共识,使用std ::版本是"正确的事情"." 呃,是的,绝对有共识认为这是正确的做法. (2认同)
  • 然后@DevSolar在字典中查找"共识"这个词.这不是标准所说的,而是C++程序员所说的 - 尤其是*他们做了什么*.有一个*原因*,实际上每个标准库实现都提供了C头,*和*的C++头也将所有内容放在全局命名空间中.:) (2认同)
  • @DevSolar 仅供参考,最近 - 在您发表评论一年多之后 - 该提案已送达委员会:http://open-std.org/JTC1/SC22/WG21/docs/papers/2017/p0619r0.html#3.5 *”最后,似乎很明显 C 头文件将被永久保留,作为与 C 和 POSIX 的重要兼容层。可能值得不推荐这些头文件,[..]"* (2认同)
  • 鉴于该标准删除了已弃用的状态,我会说全局命名空间标识符_更好_(除了重载的情况,例如“abs(3)”/“std::abs()”,这种情况要小心),因为混乱更少,而且每个人都知道“printf(3)”来自哪里。 (2认同)