4

getenv() has a C++ implementation which can be included in the header file . So it is a member of namespace std. However, the getenv() function can be get resolved correctly in my code even without a std::getenv(), which means my follow program can be compiled and run without any error and warning. So why getenv() as a name member of namespace std can get resolved without std::? My OS and compiler is Ubuntu 12.04 i386 and g++ 4.8.1 respectively.

#include <cstdlib>
#include <iostream>

int main()
{
    char * path_env;

    path_env = getenv("PATH"); //without a name resolve operation std::getenv()

    std::cout << path_env << std::endl;

    return 0;
}
Banchon
  • 43
  • 1
  • 5
  • It's [optional](http://stackoverflow.com/a/7596439/962089) whether the functions are in the global namespace as well as `std` when including `cstdlib`. – chris Apr 10 '15 at 01:22

3 Answers3

2

Try to use search before asking questions. This is duplicate of why and how does rand() exist both in global and std namespace in cstdlib?

C++11 Standard: D.5 C standard library headers
Para 3:

The header <cstdlib> assuredly provides its declarations and definitions within the namespace std. It may also provide these names within the global namespace. The header <stdlib.h> assuredly provides the same declarations and definitions within the global namespace, much as in the C Standard. It may also provide these names within the namespace std.

Community
  • 1
  • 1
fukanchik
  • 2,811
  • 24
  • 29
  • You should vote to close it as a duplicate rather than posting an answer. – Keith Thompson Apr 10 '15 at 01:39
  • i have no idea how to do that. – fukanchik Apr 10 '15 at 01:40
  • Sorry, I forgot that you need 3000 reputation points to do that. Once you get that privilege, there will be a "close" link at the bottom of each question. Meanwhile, it's probably better to post a comment on the question pointing to the duplicate; a higher-rep user can then vote to close it. http://stackoverflow.com/help/privileges/ – Keith Thompson Apr 10 '15 at 01:43
1

When you include one of the c* headers, the standard requires that the names are in the std namespace, but allows them to be first placed into the global namespace and then copied over to std.

Conversely, when you include one of the *.h headers (which are deprecated), the standard requires that the names are placed into the global namespace, but allows them to be first declared in the std namespace and copied over.

From [headers] / 4

[...] 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).

From [depr.c.headers]

enter image description here

Technically for maximum portability you should prefix names (except macros of course) in the c* headers with std, although in my limited experience I haven't come across an implementation that doesn't declare them in the global namespace as well.

user657267
  • 20,568
  • 5
  • 58
  • 77
  • Interesting, can you provide a quote from the standard? I wouldn't have allowed that though, as it may create un-portable code. – vsoftco Apr 10 '15 at 01:27
0

Your code is probably not portable. BTW, it seems to work even without including <cstdlib>. If we look carefully at the declaration:

http://en.cppreference.com/w/cpp/utility/program/getenv

we see that indeed it belongs to cstdlib, and the usual convention is that all headers that starts with c + previous C-like header are now in namespace std;, so you should be using std::.

Same happens with std::string, seems to be included by many standard library headers, although if you look at the standard, you shouldn't rely on this.

vsoftco
  • 55,410
  • 12
  • 139
  • 252