8

Take a look at this tiny program.

#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;
}

Compiling creates the following errors messages:

$ 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

Understandable. All of these exist in the "cstdlib" header which I neglected to include.
However, compiling with:

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

creates no issues.


looking at the source of the "cstdlib" header, I see the following code at the bottom:

#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

I'm not sure if that is relevant or not.. full header file code here

my ultimate question is, does the new standard guarantee that all of cstdlib will be brought in at a global namespace when you include iostream?

I can't find any documentation on the matter. Appears that way to me, does it appear that way to you?

gcc (Ubuntu/Linaro 4.6.1-9ubuntu3) 4.6.1
R. Martinho Fernandes
  • 228,013
  • 71
  • 433
  • 510
Trevor Hickey
  • 36,288
  • 32
  • 162
  • 271

1 Answers1

16

my ultimate question is, does the new standard guarantee that all of cstdlib will be brought in at a global namespace when you include iostream?

No. You should #include it yourself if you need its functionality. If you get it "for free" with <iostream>, that's a sign that your <iostream> header requires it, but then you're relying on an implementation detail of your C++ library.

Btw., #include <cstdlib> is not guaranteed to bring C functions into the global namespace (although it commonly does so in C++ implementations); it is guaranteed to put them in the namespace std:

Except as noted in Clauses 18 through 30 and Annex D, the contents of each header cname shall be the same as that of the corresponding header name.h, as specified in the C standard library (1.2) or the C Unicode TR, as appropriate, as if by inclusion. In the C++ standard library, however, the declarations (except for names which are defined as macros in C) are within namespace scope (3.3.6) of the namespace std. It is unspecified whether these names are first declared within the global namespace scope and are then injected into namespace std by explicit using-declarations (7.3.3).

(Standard, section 17.6.1.2)

Fred Foo
  • 355,277
  • 75
  • 744
  • 836
  • thats strange, I didn't have to scope atoi – Trevor Hickey May 04 '12 at 08:54
  • 1
    @Xploit: never mind my previous comment. `` does put `atoi` in the namespace `std`; if yours puts it in the global namespace as well, then that's a platform-specific extension. – Fred Foo May 04 '12 at 09:01
  • @larsmars That's not a feature, it's a bug. It's an unintended pollution of the global namespace - which is notoriously hard to avoid as library writer. gcc does a good job of slowly fleshing out those pollutions. BTW, thats one major source of miscompilation of software packets with newer version of gcc, which until then compiled fine. – Gunther Piez May 04 '12 at 09:13
  • I've just tried with Visual Studio 2010 and I have the exact same behaviour ... no need to specify std namespace. – Uflex May 04 '12 at 09:43
  • @Uflex: then MSVC has the same bug. – Fred Foo May 04 '12 at 13:46
  • 1
    @larsmans It's not a bug, as the new C++ standard allows this behavior. The `` version of C headers put everything in `std::` and might put them in the global namespace as well. The `` headers put everything in the global namespace and might put them in the `std::` namespace as well. Sorry, can't find a link at the moment. – Sjoerd May 04 '12 at 14:07
  • 2
    Link found! See comments at this answer http://stackoverflow.com/a/5079548/396551 and the official entry 456 at http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#456 – Sjoerd May 04 '12 at 14:15
  • 1
    @Sjoerd: I checked the standard text again and it seems this is indeed allowed. Still, the OP should not rely on `::atoi` being declared in ``. – Fred Foo May 04 '12 at 14:29
  • @larsmans Agree on that. I had upvoted your answer already, as I consider this a minor point. Your first comment that it is a *platform-specific extension* was correct; I should have directed my comments at drhirsch, who called it a bug. – Sjoerd May 04 '12 at 14:37