Why was getenv standardised but not setenv?

The C90 standard includes getenv(); therefore, the C++98 standard did too.

When the C standard was originally created, the precedent for environment setting was putenv(); the setenv() function was not devised until later. The standard committee avoided creating new functions when it could, but also avoided standardizing problematic functions when possible (yes, localeconv() and gets() are counter-examples). The behaviour of putenv() is problematic. You have to pass it memory which is not of automatic duration, but you can’t know whether you can ever use it again. It’s like a forced memory leak. It was A Good Thing™ that putenv() was not standardized.

The rationale for the C standard explicitly says (§7.20.4.5, p163):

A corresponding putenv function was omitted from the Standard, since its utility outside a multi-process environment is questionable, and since its definition is properly the domain of an operating system standard.

Platform-specific APIs step in and provide the missing functionality in a way suitable to them.


The first editions of the POSIX standard (1988 trial use; 1990) did not include setenv() or putenv(). The X/Open Portability Guide (XPG) Issue 1 did include putenv() based on its appearance in the SVID (System V Interface Definition) — which did not include setenv(). The XPG Issue 6 added setenv() and unsetenv() (see the history sections for the functions at the URLs linked to). Curiously, on a Mac running macOS Sierra 10.12.6, man 3 setenv has a history section that identifies:

The functions setenv() and unsetenv() appeared in Version 7 AT&T UNIX. The putenv() function appeared in 4.3BSD-Reno.

This is unexpected and probably erroneous since the UNIX Programmer’s Manual Vol 1 (1979) does not include any of putenv(), setenv() or unsetenv(). The putenv() function was added to the AT&T variants of Unix at some stage in the 80s; it was in the SVID and documented by the time SVR4 was released in 1990 and may have been part of System III. I think they almost have the platforms reversed. 4.3BSD-Reno was released in June 1990, after both the first C and POSIX standards were released.

There was some discussion in comments with Random832 , now removed, mentioning TUHS – The Unix Heritage Society as a source of information about ancient versions of Unix. The chain included my observation: If nothing else, this discussion emphasizes why the standards committees did well to steer clear of ‘setting the environment’! It appears that putenv() was not in 7th Edition UNIX, contrary to my memory. I’m fairly sure it was available in a system I used from 1983, which was a lot of 7th Edition with some material from System III, some from PWB. It is a part of SVR4 (I’ve a manual for that), and was defined in some version of the SVID (probably before SVR4).

The C rationale also mentions concerns about gets() but included it despite those concerns; it was (very sensibly) removed from C11, of course (but POSIX still refers to C99, not C11).

Leave a Comment

Hata!: SQLSTATE[HY000] [1045] Access denied for user 'divattrend_liink'@'localhost' (using password: YES)