2015-04-10 7 views
3

getenv() имеет реализацию C++, которая может быть включена в файл заголовка. Таким образом, он является членом пространства имен std. Однако функция getenv() может быть правильно решена в моем коде даже без std :: getenv(), что означает, что моя следующая программа может быть скомпилирована и запущена без каких-либо ошибок и предупреждений. Итак, почему getenv() как член имени пространства имен std может быть разрешен без std ::? Моя ОС и компилятор - Ubuntu 12.04 i386 и g ++ 4.8.1 соответственно.Почему getenv() может получить имя без разрешения std ::?

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

Это [необязательно] (http://stackoverflow.com/a/7596439/962089), являются ли функции в глобальном пространстве имен, а также 'std' при включении' cstdlib'. – chris

ответ

1

Попробуйте использовать поиск, прежде чем задавать вопросы. Это дубликат why and how does rand() exist both in global and std namespace in cstdlib?

C++ 11 Стандарт: D.5 C стандартная библиотека заголовки
Para 3:

Заголовок <cstdlib> уверенно предоставляет свои декларации и определения в пространстве имен std. Он также может предоставлять эти имена в глобальном пространстве имен. Заголовок <stdlib.h>, безусловно, предоставляет те же декларации и определения в глобальном пространстве имен, что и в стандарте C. Он также может предоставлять эти имена в пространстве имен std.

+0

Вы должны проголосовать, чтобы закрыть его как дубликат, а не публиковать ответ. –

+0

Я понятия не имею, как это сделать. – fukanchik

+0

Извините, я забыл, что вам нужно 3000 очков репутации, чтобы это сделать. Как только вы получите эту привилегию, в нижней части каждого вопроса будет «близкая» ссылка. Между тем, вероятно, лучше оставить комментарий по вопросу, указывающему на дубликат; пользователь более высокого уровня может затем проголосовать, чтобы закрыть его. http://stackoverflow.com/help/privileges/ –

0

Ваш код, вероятно, не переносится. BTW, это seems to work даже без включения <cstdlib>. Если мы внимательно посмотрим на декларации:

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

мы видим, что на самом деле она принадлежит cstdlib, а обычное соглашение состоит в том, что все заголовки, которые начинаются с + предыдущего заголовка c C-как теперь в namespace std;, так вы должны использовать std::.

То же самое происходит с std::string, кажется, включен многими стандартными заголовками библиотек, хотя, если вы посмотрите на стандарт, вы не должны полагаться на это.

1

Когда вы include один из заголовков * с, стандарт требует , что имена находятся в пространстве имен std, но позволяет их быть первым помещен в глобальное пространство имен, а затем скопировать на std.

С другой стороны, когда вы include один из * .h заголовков (которые являются устаревшими), стандарт требует, что имена помещаются в глобальное пространство имен, но позволяет им быть первым объявлены в std пространства имен и скопировали.

Из [заголовков]/4

[...] Не определено, являются ли эти имена первых объявлены в глобальной области видимости пространства имен в и затем вводят в патезрасе с помощью явных с использованием деклараций (7.3.3).

С [depr.c.headers]

enter image description here

Технически для максимальной портативности вы должны PREfix имена (кроме макросов, конечно) в C * заголовки с std, хотя в моем ограниченном опыте Я не сталкивался с реализацией, которая также не объявляет их в глобальном пространстве имен.

+0

Интересно, можете ли вы предоставить цитату из стандарта? Я бы не допустил этого, так как это может создать неспасный код. – vsoftco