why getenv() can get name resolved without a std::?

3.2k views Asked by At

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

There are 3 answers

3
fukanchik On BEST ANSWER

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.

0
vsoftco On

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.

1
user657267 On

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.