【问题标题】:why getenv() can get name resolved without a std::? [duplicate]为什么 getenv() 可以在没有 std:: 的情况下解析名称? [复制]
【发布时间】:2015-04-10 01:16:45
【问题描述】:

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

【问题讨论】:

  • 函数是否在全局命名空间中为optional,包含cstdlib时为std

标签: c++ getenv token-name-resolution


【解决方案1】:

在提问之前尝试使用搜索。这是why and how does rand() exist both in global and std namespace in cstdlib?的副本

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

标题&lt;cstdlib&gt; 确实在命名空间std 中提供了它的声明和定义。它还可以在全局命名空间中提供这些名称。标题&lt;stdlib.h&gt; 确实在全局命名空间中提供了相同的声明和定义,就像在 C 标准中一样。它还可以在命名空间std 中提供这些名称。

【讨论】:

  • 您应该投票将其作为重复项关闭,而不是发布答案。
  • 我不知道该怎么做。
  • 抱歉,我忘记了你需要 3000 声望点才能做到这一点。一旦您获得该特权,每个问题的底部都会有一个“关闭”链接。同时,最好对指向重复的问题发表评论;然后,更高代表的用户可以投票关闭它。 stackoverflow.com/help/privileges
【解决方案2】:

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

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

来自 [标题] / 4

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

来自 [depr.c.headers]

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

【讨论】:

  • 有趣,你能提供一个标准的报价吗?不过我不会允许这样做,因为它可能会创建不可移植的代码。
【解决方案3】:

您的代码可能不可移植。顺便说一句,它 seems to work 即使不包括 &lt;cstdlib&gt;。如果我们仔细看一下声明:

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-04-17
    • 1970-01-01
    • 1970-01-01
    • 2016-01-25
    • 1970-01-01
    • 2020-06-15
    • 1970-01-01
    相关资源
    最近更新 更多