C90标准包括getenv()
;因此,C++ 98标准也是如此。
当C标准最初创建时,环境设置的先例是putenv()
; setenv()
函数直到后来才被设计出来。标准委员会在可能时避免了创建新功能,但也避免了在可能的情况下标准化有问题的功能(是的,localeconv()
和gets()
是反例)。 putenv()
的行为有问题。你必须传递它不是自动持续时间的记忆,但是你不知道你是否可以再次使用它。这就像是一个强制内存泄漏。这是一件好事™,putenv()
没有标准化。
的rationale为C标准明确地说(§7.20.4.5,P163):
相应putenv
函数从标准省略,因为它的多进程环境之外效用是有问题的,并因为它的定义恰好是操作系统标准的领域。
特定于平台的API介入并以适合他们的方式提供缺少的功能。
POSIX标准的第一版本(1988试用; 1990)不包括setenv()
或putenv()
。 X/Open可移植性指南(XPG)问题1确实包括putenv()
,其基于其在SVID(System V Interface Definition)中的外观(其不包括setenv()
)。 XPG第6期增加了setenv()
和unsetenv()
(请参阅链接到URL的功能的历史部分)。奇怪的是,在Mac上运行MacOS的塞拉利昂10.12.6,man 3 setenv
有标识历史部分:
功能SETENV()和unsetenv()出现在第7版AT &牛逼UNIX。 putenv()函数出现在4.3BSD-Reno中。
这是意想不到的,可能错误的,因为UNIX Programmer's Manual Vol 1(1979年),不包括任何的putenv()
,setenv()
或unsetenv()
。在80年代的某个阶段,将putenv()
函数添加到Unix的AT变体中;它在SVID中,并且在SVR4于1990年发布并且可能已经成为System III的一部分时形成文件。我认为他们几乎已经颠倒了平台。 4.3BSD-Reno于1990年6月发布,在首批C和POSIX标准发布后发布。
有在评论与Random832一些讨论,现在取出,提TUHS – The Unix Heritage Society为约古Unix版本的信息来源。该链包括我的观察:如果没有别的,这个讨论强调了为什么标准委员会做得好,以避免'设置环境'!看起来putenv()
不在第7版UNIX中,与我的记忆相反。我相当肯定它在1983年使用的系统中可用,这是一个来自系统III的一些材料的第七版,有些来自PWB。它是SVR4的一部分(我有一个手册),并在SVID的某个版本中定义(可能在SVR4之前)。
C的基本原理还提到了关于gets()
的担忧,但包括它,尽管有这些顾虑;当然,它(非常明智地)从C11中删除(但POSIX仍然指C99,而不是C11)。
POSIX'setenv()'和'getenv()'不是线程安全的,IIRC。也许以某种方式与此有关? – tambre
@tambre令人怀疑,'std :: getenv'是线程安全的,因为C++ 11(根据cppreference) – Borgleader
推测,但我会说是因为有一个相对简单的'std :: getenv'定义可以被标准化。串入,串出。补码不是那么直截了当,并且*非常*实现相关。 – StoryTeller