【问题标题】:c++11 includes <cstdlib> at times when c++03 will not?c++11 有时包含 <cstdlib> 而 c++03 不包含?
【发布时间】:2012-05-04 08:46:33
【问题描述】:

看看这个小程序。

#include <iostream>

int main(){

  int var = atoi("-99");      //convert string to int
  var = abs(var);             //takes absolute value
  std::cout << var+1 <<'\n';  //outputs 100

  return EXIT_SUCCESS;
}

编译会产生以下错误消息:

$ g++ -o main main.cpp
main.cpp: In function ‘int main()’:
main.cpp:5:13: error: ‘atoi’ was not declared in this scope
main.cpp:6:16: error: ‘abs’ was not declared in this scope
main.cpp:9:10: error: ‘EXIT_SUCCESS’ was not declared in this scope

可以理解。所有这些都存在于我忽略的“cstdlib”标头中。
但是,编译:

$ g++ -std=c++0x -o main main.cpp 

不会产生任何问题。


查看“cstdlib”标头的来源,我在底部看到以下代码:

#ifdef __GXX_EXPERIMENTAL_CXX0X__
#  if defined(_GLIBCXX_INCLUDE_AS_TR1)
#    error C++0x header cannot be included from TR1 header
#  endif
#  if defined(_GLIBCXX_INCLUDE_AS_CXX0X)
#    include <tr1_impl/cstdlib>
#  else
#    define _GLIBCXX_INCLUDE_AS_CXX0X
#    define _GLIBCXX_BEGIN_NAMESPACE_TR1
#    define _GLIBCXX_END_NAMESPACE_TR1
#    define _GLIBCXX_TR1
#    include <tr1_impl/cstdlib>
#    undef _GLIBCXX_TR1
#    undef _GLIBCXX_END_NAMESPACE_TR1
#    undef _GLIBCXX_BEGIN_NAMESPACE_TR1
#    undef _GLIBCXX_INCLUDE_AS_CXX0X
#  endif
#endif

我不确定这是否相关。完整的头文件代码here

我的最终问题是,当您包含 iostream 时,新标准是否保证所有 cstdlib 都将被引入全局命名空间?

我找不到有关此事的任何文件。在我看来是这样,在你看来是这样吗?

gcc (Ubuntu/Linaro 4.6.1-9ubuntu3) 4.6.1

【问题讨论】:

  • 顺便说一句,这个标题完全是误导。 C++11 C++。它不是一种新的独立语言。

标签: c++ namespaces c++11 g++


【解决方案1】:

我的最终问题是,新标准是否保证当您包含 iostream 时所有 cstdlib 都将被引入全局命名空间?

没有。如果您需要它的功能,您应该自己 #include 它。如果您使用&lt;iostream&gt;“免费”获得它,则表明您的&lt;iostream&gt; 标头需要它,但是您依赖于C++ 库的实现细节。

顺便说一句,#include &lt;cstdlib&gt; 不能保证将 C 函数带入全局命名空间(尽管它通常在 C++ 实现中这样做);保证将它们放在命名空间std

除了第 18 到 30 条和附录 D 中的说明外,每个标头 cname 的内容应与 C 标准库 (1.2) 或 C 中规定的相应标头 name.h 的内容相同Unicode TR,视情况而定,好像通过包含。但是,在 C++ 标准库中,声明(在 C 中定义为宏的名称除外)在命名空间 std 的命名空间范围 (3.3.6) 内。未指定这些名称是否首先在全局命名空间范围内声明,然后通过显式 using-declarations (7.3.3) 注入命名空间 std

(标准,第 17.6.1.2 节)

【讨论】:

  • 这很奇怪,我不必对 atoi 进行范围
  • @Xploit:别介意我之前的评论。 &lt;cstdlib&gt; 确实将 atoi 放在命名空间 std 中;如果你的也把它放在全局命名空间中,那么这是一个特定于平台的扩展。
  • @larsmans 这不是错误,因为新的 C++ 标准允许这种行为。 &lt;cfoo&gt; 版本的 C 头文件将所有内容放在 std:: 中,并且也可能将它们放在全局命名空间中。 &lt;foo.h&gt; 标头将所有内容放在全局命名空间中,也可能将它们放在 std:: 命名空间中。抱歉,暂时找不到链接。
  • 链接找到了!请参阅此答案 stackoverflow.com/a/5079548/396551 的 cmets 和 open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#456 的官方条目 456
  • @Sjoerd:我再次检查了标准文本,看来这确实是允许的。尽管如此,OP 不应依赖在 &lt;cstdlib&gt; 中声明的 ::atoi
猜你喜欢
  • 2017-07-06
  • 1970-01-01
  • 2014-11-18
  • 1970-01-01
  • 1970-01-01
  • 2012-03-09
  • 1970-01-01
  • 1970-01-01
  • 2023-04-02
相关资源
最近更新 更多