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

时间:2015-09-16 10:26:51

标签: c++ language-lawyer std

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

我的问题实际上是一种语义。在C ++代码中(使用最新版本的GCC编译器),我可以调用printf("Hello world!);std::printf("Hello world!);,它的工作方式完全相同。在我使用的参考文献中,它也显示为std::printf("Hello world!);

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

8 个答案:

答案 0 :(得分:98)

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

  

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

     
      
  1. 与C标准库兼容......
  2.   
  3. 每个C标题,每个标题都有 name.h 形式的名称,就好像每个名称放在标准中一样   相应的 cname 标头的库命名空间位于全局命名空间范围内。 未指定是否首先在命名空间范围内声明或定义这些名称(3.3.6) 命名空间 std ,然后将其注入显式使用声明(7.3.3)。
  4. 的全局命名空间范围   
  5. 示例:标题<cstdlib> 确定在命名空间内提供声明和定义   std 即可。它还可以在全局命名空间中提供这些名称。标题<stdlib.h> 确定在全局命名空间中提供相同的声明和定义,就像在C标准中一样。它   也可以在命名空间std中提供这些名称。
  6.   

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

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

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

换句话说:更喜欢

#include <cstdio>

int main() {
    std::printf("Hello world\n");
}

#include <stdio.h>

int main() {
    printf("Hello world\n");
}

答案 1 :(得分:77)

<cmeow>始终提供::std::purr,可能提供也可能不提供::purr

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

使用保证由您提供的标题提供的表单。

答案 2 :(得分:7)

不,不管怎样,你都没事。

原始意图是<___.h>标题是将所有内容放在全局命名空间中的C版本,而<c___>标题将是C ++ - ified版本,它将所有内容放在std命名空间中。

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

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

答案 3 :(得分:3)

唯一的区别是,在std::printf()中,通过添加std::范围解析,您可以保护自己免于将来编写具有相同名称的函数的人,这会导致名称空间冲突。两种用法都将导致完全相同的OS API调用(您可以通过运行strace your_program在Linux下进行检查)。

我发现有人不太可能命名这样的函数,因为printf()是最常用的函数之一。此外,在C ++中,iostream s优先于调用cstdio函数,如printf。

答案 4 :(得分:3)

来自C ++ 11标准:

  

每个C头,每个头都有一个名称为name.h的行为   好像每个名称都放在标准库命名空间中   相应的cname标头放在全局名称空间中   范围。未指定是否首先声明这些名称或   在命名空间std的命名空间范围(3.3.6)中定义并且是   然后通过explicit注入全局命名空间范围   使用声明(7.3.3)。

因此,如果您使用<cstdio>,则可以确定printf位于namespace std,因此不在全局命名空间中。
使用全局命名空间会产生名称冲突。 这不是C ++方式。

因此,我使用<cstdio>标题并建议您这样做。

答案 5 :(得分:3)

根据我自己的惯例:使用std::前缀。否则,有一天abs 非常痛苦地咬你,以防你使用浮点数。

非限定abs是指某些平台上int上定义的功能。在其他人身上它超载了。但是std::abs总是为所有类型重载。

答案 6 :(得分:2)

仅使用printf而不使用std::可能会产生一些名称冲突,并被许多c ++开发人员认为是一种不好的做法。谷歌是你的朋友,但这里有一些链接,希望这有帮助

Why is "using namespace std" considered bad practice? http://www.cplusplus.com/forum/beginner/61121/

答案 7 :(得分:2)

在stdio

  

这是标准C库头文件@c stdio.h的C ++版本,   它的内容(大部分)与标题相同,但都是   包含在命名空间@c std中(除了定义的名称)   作为C)中的宏。

所以它不应该有任何区别。