8

看看这个小程序。

#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

我不确定这是否相关..完整的头文件代码在这里

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

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

gcc (Ubuntu/Linaro 4.6.1-9ubuntu3) 4.6.1
4

1 回答 1

16

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

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

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

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

(标准,第 17.6.1.2 节)

于 2012-05-04T08:51:27.513 回答