3

getenv() 有一个 C++ 实现,可以包含在头文件中。所以它是命名空间std的成员。但是,即使没有 std::getenv(),也可以在我的代码中正确解析 getenv() 函数,这意味着我的后续程序可以编译和运行而不会出现任何错误和警告。那么为什么 getenv() 作为命名空间 std 的名称成员可以在没有 std:: 的情况下得到解析?我的操作系统和编译器分别是 Ubuntu 12.04 i386 和 g++ 4.8.1。

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

3 回答 3

1

当您使用include其中一个 c* 标头时,标准要求名称位于std命名空间中,但允许它们首先放入全局命名空间,然后复制到std.

相反,当您使用include其中一个 *.h 标头(已弃用)时,标准要求将名称放入全局命名空间,但允许它们首先在std命名空间中声明并复制过来。

来自 [标题] / 4

[...]未指定这些名称是否首先在全局命名空间范围内声明,然后通过显式使用声明(7.3.3)注入命名空间 std。

来自 [depr.c.headers]

在此处输入图像描述

从技术上讲,为了获得最大的可移植性,您应该在 c* 标头中使用 前缀名称(当然宏除外)std,尽管在我有限的经验中,我还没有遇到没有在全局命名空间中声明它们的实现。

于 2015-04-10T01:25:02.793 回答
1

在提问之前尝试使用搜索。这与 rand() 为何以及如何在 cstdlib 的全局和 std 命名空间中存在重复?

C++11 标准:D.5 C 标准库头文件
第 3 段:

标头<cstdlib>确实在命名空间中提供了它的声明和定义std。它还可以在全局命名空间中提供这些名称。头文件<stdlib.h>在全局命名空间中确实提供了相同的声明和定义,就像在 C 标准中一样。它还可以在命名空间内提供这些名称std

于 2015-04-10T01:27:25.487 回答
0

您的代码可能不可移植。顺便说一句,即使不包括<cstdlib>. 如果我们仔细看一下声明:

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

我们看到它确实属于cstdlib,并且通常的约定是所有以c+ 前一个 C 类头文件开头的头文件现在都在namespace std;,所以你应该使用std::.

std::string, 似乎也包含在许多标准库头文件中,但如果您查看标准,您不应该依赖它。

于 2015-04-10T01:20:58.820 回答