Ответ 1
Стандарт C90 включает getenv()
; поэтому также использовался стандарт С++ 98.
Когда первоначально был создан стандарт C, прецедент для настройки среды был putenv()
; функция setenv()
не была разработана до конца. Стандартный комитет избегал создавать новые функции, когда мог, но также избегал стандартизации проблемных функций, когда это возможно (да, localeconv()
и gets()
являются встречными примерами). Поведение putenv()
проблематично. Вы должны передать ему память, которая не является автоматической продолжительностью, но вы не можете знать, сможете ли вы когда-либо использовать ее снова. Это похоже на вынужденную утечку памяти. Это была хорошая вещь, которая putenv()
не была стандартизирована.
rationale для стандарта C явно говорит (§7.20.4.5, p163):
Соответствующая функция
putenv
была исключена из Стандарта, так как ее утилита вне многопроцессорной среды сомнительна и поскольку ее определение является надлежащим образом доменом стандарта операционной системы.
API-интерфейсы, специфичные для платформы, входят в систему и предоставляют недостающие функциональные возможности, подходящие для них.
Первые выпуски стандарта POSIX (1988 trial use, 1990) не включали setenv()
или putenv()
. Руководство по переносимости X/Open (XPG) Проблема 1 включила putenv()
в зависимости от ее появления в SVID (Определение интерфейса V-интерфейса), который не включал setenv()
. В XPG Issue 6 добавлены setenv()
и unsetenv()
(см. Разделы истории для функций по связанным URL). Любопытно, что на Mac, работающем под управлением macOS Sierra 10.12.6, man 3 setenv
имеет раздел истории, который идентифицирует:
Функции setenv() и unsetenv() появились в версии 7 AT & T UNIX. Функция putenv() появилась в 4.3BSD-Reno.
Это неожиданно и, вероятно, ошибочно, поскольку Руководство для программиста UNIX Vol 1 (1979) не содержит ни одного из putenv()
, setenv()
или unsetenv()
. Функция putenv()
была добавлена к вариантам AT & T Unix на некотором этапе 80-х годов; он был в SVID и документирован к тому времени, когда SVR4 был выпущен в 1990 году и, возможно, был частью System III. Я думаю, что у них почти нет платформы. 4.3BSD-Reno был выпущен в июне 1990 года после того, как были выпущены первые C и POSIX.
Было высказано некоторое обсуждение в комментариях с Random832, теперь удалено, отметив TUHS - Общество наследия Unix как источник информации о древних версиях Unix. Цепочка включала мое наблюдение: если ничего другого, в этом обсуждении подчеркивается, почему комитеты по стандартам преуспели, чтобы избегать "установления окружающей среды"! Похоже, что putenv()
не было в 7-м выпуске UNIX, вопреки моей памяти. Я уверен, что он был доступен в системе, которую я использовал с 1983 года, в которой было много 7-го издания с некоторыми материалами из System III, некоторые из PWB. Это часть SVR4 (для этого есть руководство), и она была определена в некоторой версии SVID (вероятно, до SVR4).
В обосновании C также упоминаются проблемы, связанные с gets()
, но включенные в него, несмотря на эти проблемы; Разумеется, он был (очень разумно) удален из C11 (но POSIX по-прежнему относится к C99, а не к C11).