Is char *envp[] as a third argument to main() portable
Solution 1
The function getenv
is the only one specified by the C standard. The function putenv
, and the extern environ
are POSIX-specific.
EDIT
The main
parameter envp
is not specified by POSIX but is widely supported.
An alternative method of accessing the environment list is to declare a third argument to the main() function:
int main(int argc, char *argv[], char *envp[])
This argument can then be treated in the same way as environ, with the difference that its scope is local to main(). Although this feature is widely implemented on UNIX systems, its use should be avoided since, in addition to the scope limitation, it is not specified in SUSv3.
Solution 2
It isn't portable. *envp[]
is a traditional UNIX thing, and not all modern UNIX systems implement it.
Also as a side note you could access envp by doing a pointer traversal over *argv[]
, overflowing it...but i don't think that can be considered safe programming. If you take a look at the process memory map you will see that envp[]
is just above argv[]
.
Solution 3
The Standard describes two formats for main
(see 5.1.2.2.1 in the C99 Standard (pdf))
a) int main(void)
and
b) int main(int argc, char **argv)
or equivalent
and it allows implementations to define other formats (which can allow a 3rd argument)
c) or in some other implementation-defined manner.
Solution 4
The 3rd argument is valid in Microsoft C and GNU GCC:
Comments
-
Sangeeth Saravanaraj almost 2 years
In order to get an environment variable in a
C
program, one could use the following:getenv()
extern char **environ;
But other than the above mentioned, is using
char *envp[]
as a third argument tomain()
to get the environment variables considered part of the standard?#include <stdio.h> int main(int argc, char *argv[], char *envp[]) { while(*envp) printf("%s\n",*envp++); }
Is
char *envp[]
portable? -
Daniel Fischer about 12 yearsAn implementation may provide further formats for
main
, but these two are the only ones guaranteed to be present in any hosted implementation. -
R.. GitHub STOP HELPING ICE about 12 yearsAnd you can go past the environment too and examine
auxv
... ;-) -
skyel about 12 yearsWhat is usually stored in auxv, because i was just wondering the other days why where the fields after envp constant(between runs)?
-
R.. GitHub STOP HELPING ICE about 12 yearsLook in
elf.h
for the macros beginning withAT_
. Some of the more interesting things areAT_SECURE
,AT_RANDOM
,AT_EXECFN
,AT_HWCAP
, and the uid/gid ones. Otherwise they're mostly of interest to the dynamic linker and libc init code. The format ofauxv
is pairs of system-word-size integers, the first of which is one of theAT_
constants (a tag) and the second of which is the value associated with that tag (possibly a pointer, depending on the tag). -
Jonathan Leffler about 10 yearsNote that the C standard recognizes this as a common alternative — even C89 mentioned it in Annex G (Portability Issues); it is in Annex J (Portability Issues) in both C99 and C11.
-
Braden Best over 8 yearsWhat about using a pointer to find the end of argv, and going one step further?
char **find = argv, **envp; while(*find) find++; envp = find + 1;
Probably undefined behavior since an OS isn't guaranteed to put environment stuff after argv's last arg... -
ben over 3 yearsIt does not work with (at least) z/OS 2.4 and xlc/c99/c89 on the IBM Mainframe. There is a POSIX solution.
-
mtraceur over 2 yearsMore traditional/idiomatic and concise version of the last comment's way:
char **envp = argv; while(*envp++);