Machine specific predefined names

terry terry at wsccs.UUCP
Sat Mar 12 17:45:36 AEST 1988


In article <229 at sdrc.UUCP>, scjones at sdrc.UUCP (Larry Jones) writes:
> In article <17033 at watmath.waterloo.edu>, rbutterworth at watmath.waterloo.edu (Ray Butterworth) writes:
> > But consider a different related problem:
> > 
> >     #include <stdlib.h>
> >     #include <stdio.h>
> >     int putchar(int n) { abort(n); }
> >     main() { perror("xx"); }
> > 
> > Now if perror() needs putchar() to write the message, will it use
> > my version of putchar or an internal version, say _putchar()?
> [stuff omitted for brevity]
> > I didn't see anything in the standard to indicate that either of
> > these behaviours is right or wrong.
> 
> The draft clearly indicates in section 4.1.2 that every external identifier
> declared in a standard header is reserved whether the header is included or
> not and that redefining a reserved external identifier results in undefined
> behaviour.  Thus, either behaviour is acceptable and your program is not
> strictly portable.

	I assume by the draft, you mean the ANSI 'standard', and _not_
conscription (although they seem to be similar in that neither is desirable).

	In specifying either behavior, the draft would have to dictate the
actions of the linker.  In general, most C compilers based on AT&T's idea
of a portable C compiler, simply generate symbol table data, whether in the
form of quads or what have you, and it is resolved by the linker at link time.

	What this means to Ray is that his question devolves to one of "how
will the linker act under the standard?"  This is the decision of the linker.
As far as I know (about 13 feet, give or take 4 inches), ANSI has _not_ gone
and tried to screw up everyone's idea of a linker with some farcical and
unrealistic 'linker' standard.  This means that if you are using AT&T's
compiler, I can probably safely assume you are using their linker.  What
this means (although, strictly, Larry _is_ correct in that either behavior
is possible) is that you should expect the linker to resolve all external
references (such as those made in the header, 'reserving' things) by first
finding them in your code, then, if the external reference could not be
found, resolving them from the library.  This means that in 99% of the
cases, your putchar would be used.

	Our company has used redefinition of library functions (printf(),
most notably) for a number of years, and our has always been used _first_.
This works on every version of VMS I've played with (4.3-4.7) _and_ every
version of UNIX, as well as Aztec C for various machines.  The only problem
was warning errors of "redefined function" from the VMS linker, which likes
to drag in every function at once, as they were all compiled in the same module
(an ugly thing to do).

	I know of over 200 machines that work this way, > 120 from personal
experience.  Contrary to what Larry has said, Ray, I know of no machine that
does _NOT_ work this way.  I think you would be pretty safe in assuming that
_all_ machines work this way.  If they don't, then piss on them.  Their
manufacturers will soon find out that they have to change the behavior of
their linkers, or not have products ported to them.  I defend this position
by pointing out that while C is standard, libraries are not, and to get
portable code depending on a library function, you MUST rewrite the library
function for it to operate consitantly.  For example, get 5 UNIX machines,
of any flavor, and compile and run the following fragment:

	#include <stdio.h>
	main()
	{
		printf( NULL);
	}

Some systems will core dump, some systems will do nothing, and others will
print the string '(NULL)' (my quotes).

I don't believe everybody will rewrite their UNIX in ANSI C, anyway, so lets
all hold our breath, and it will go away, leaving only K&R and some idiots
blinking their eyes at the sudden light.

				terry at wsccs



More information about the Comp.lang.c mailing list