为什么getenv是标准化的,而不是setenv? 从答案和评论中,我理解了C++标准所定义的,但是 SETENV 不是。事实上,下面的节目 #包括 #包括 int main(int argc,字符**argv) { std::cout

为什么getenv是标准化的,而不是setenv? 从答案和评论中,我理解了C++标准所定义的,但是 SETENV 不是。事实上,下面的节目 #包括 #包括 int main(int argc,字符**argv) { std::cout,c++,c,language-lawyer,C++,C,Language Lawyer,setenv在某些原始环境中是不可能的 getenv允许您查看您的环境。使用exec[lv][p][e]创建新进程允许您使用继承的或新的环境创建子进程 但是,setenv会修改调用进程的状态,这并不总是可能的 我猜这是因为它增加了调用者的可写接口,最初并不需要,而且现在存在安全风险。C90标准包括;因此,C++98标准也包括在内 最初创建C标准时,环境设置的先例是;直到后来才设计该功能。标准委员会避免在可能时创建新功能,但也避免在可能时标准化有问题的功能(是的,并且是反例)。putenv()的行

setenv在某些原始环境中是不可能的

getenv允许您查看您的环境。使用exec[lv][p][e]创建新进程允许您使用继承的或新的环境创建子进程

但是,setenv会修改调用进程的状态,这并不总是可能的

我猜这是因为它增加了调用者的可写接口,最初并不需要,而且现在存在安全风险。

C90标准包括;因此,C++98标准也包括在内

最初创建C标准时,环境设置的先例是;直到后来才设计该功能。标准委员会避免在可能时创建新功能,但也避免在可能时标准化有问题的功能(是的,并且是反例)。
putenv()的行为
是有问题的。你必须向它传递不是自动持续时间的内存,但你无法知道是否可以再次使用它。这就像是强制内存泄漏。这是一件好事™
putenv()
未标准化

C标准的标准明确规定(§7.20.4.5,第163页):

标准中省略了相应的
putenv
函数,因为它在多进程环境之外的实用性值得怀疑,而且它的定义正好是操作系统标准的领域

特定于平台的API介入并以适合它们的方式提供缺少的功能


POSIX标准的第一版(1988年试用;1990年)没有包括
setenv()
putenv()
。根据其在SVID()中的外观,X/Open Portability Guide()第1期确实包括
putenv()
。SVID()中没有包括
setenv()
。XPG第6期增加了
setenv()
unsetenv()
(有关链接到的URL的函数,请参见历史记录部分)。奇怪的是,在运行macOS Sierra 10.12.6的Mac上,
man 3 setenv
有一个历史记录部分,该部分标识:

函数setenv()和unsetenv()出现在版本7 AT&T UNIX中。函数putenv()出现在4.3BSD-Reno中

这是出乎意料的,可能是错误的,因为(1979)不包括
putenv()
setenv()
unsetenv()
功能在80年代的某个阶段被添加到Unix的AT&T变体中;它在SVID中,并在SVR4于1990年发布时记录在案,可能已经成为System III的一部分。我认为它们的平台几乎完全颠倒了。它是在1990年6月发布的,在第一个C和POSIX标准发布之后发布的

在评论中有一些讨论,现在被删除了,提到它是有关Unix古代版本的信息来源。这条链包括我的观察:如果没有其他内容,这一讨论强调了为什么标准委员会在避免“设置环境”方面做得很好!似乎
putenv()
与我的记忆相反,它不在第七版UNIX中。我很确定它在我从1983年开始使用的系统中是可用的,这是很多第七版,其中一些材料来自system III,一些来自PWB。它是SVR4的一部分(我有一本手册),并且在SVID的某些版本中定义(可能在SVR4之前)


C的基本原理还提到了关于
gets()
的问题,但尽管有这些问题,还是将其包括在内;当然,它(非常明智地)从C11中删除了(但POSIX仍然是指C99,而不是C11)。

@tambre怀疑,
std::getenv
自C++11以来是线程安全的(根据cppreference)推测,但我要说的是,对于
std::getenv
有一个相对简单的定义,可以标准化。字符串输入,字符串输出。补码不是那么直接,并且非常依赖于实现。7.22.4.6中有
getenv
函数,但没有相应的
setenv()所以,无论是从C++中省略逻辑,它都可能适用于C。因此我添加了C标签。(和语言律师标签……)我同意@ Staytter的猜测,我想没有明确的答案,所以我投票赞成“主要是基于意见的”。,尽管这个问题确实很有趣……我投票重新打开了——并不是说这有多大区别——因为事实证明,有一份文件给出了省略一个非常相关的函数的理由。“修改调用过程的状态”——真的吗?C可以指定这样的平台(如果存在的话)在它们的
getenv()
/
putenv()中提供足够的隔离
实现以提供每个进程环境的效果。@TobySpeight:他的意思是调用
getenv
的进程。啊,我明白了;我误解为是指父进程。谢谢你指出这一点,@Cheersandhth-Alf@TobySpeight即使考虑到你认为这意味着什么,提供一个孤立的环境可能会我被认为对自然提供全局环境或根本不提供环境的系统来说负担太大了(一致的getenv总是可以返回null)。显然POSIX;-)POSIX上的约束与C上的约束不同;结果是不同的选择。