Chris said:
.... snip ...
Unfortunately, this startup module also refers to a global variable
named "environ", because the system-supplied C library does the
same (in getenv()).
The fix (in this case) is not to avoid loading certain modules,
but rather to rename the global variable, e.g., change it to
__environ. For backwards compatibility, these (ELF-based) systems
provide a "weak association" directive under which the "true name"
(now __environ) can be "loosely attached" to the old, intrusive
"environ" name. If the programmer supplies any instance of "environ",
the programmer's version breaks the weak attachment so that the
system's __environ is an entirely separate variable; but if the
program only ever says "extern char **environ;" -- only refers to
it, rather than defining it -- the weak link holds and the old code
continues to compile and link.
I think the proper thing here is to have the startup module
variable, etc. named __environ (or something else in the system
space). This is used to place the appropriate data in the
appropriate place on the stack (assuming a stack), and is
published in the startup modules exported names.
Now, somewhere in the process of compiler startup, it knows
whether it is an ansi or extended compiler. If extended, it calls
code like:
genline("#define environ __environ\n");
which magically moves the item into the users namespace.
I can see complications because this should probably be local to
main, and I gather from some other posts that "environ" must not
appear in the system headers per POSIX. However I would consider
the first requirement to be "make it C99 compliant", and full
POSIX compliancy is subordinate.
The proper way would be to have an added header for POSIX
standard, which could handle all these silly differences. Just
omit it to strip the POSIX stuff. IMHO.