[comp.lang.c] Machine specific predefined names

bvs@light.uucp (Bakul Shah) (02/18/88)

I have some questions, quibbles really, for the __STDC__ experts
on the net.  Please, definitive answers only!

Many C compilers predefine some names to indicate a subset of
{processor, os} {family, a specific member of that family}; some
such names are mc68k, mc68000, vax, unix, etc.

Now our local stdc expert says that an ANSII compatible compiler
can not use these names as they belong to the name space reserved
for the user.  Such a compiler may only predefine names that
belong to the name space reserved for the implementer, that is,
names matching the ``_[A-Z_][0-9A-Za-z_]*'' pattern.  He suggests
that ANSII C compilers for the AMD29000 processor predefine _Am29k
(for this family) and _Am29000 (for this specific processor).

Doing so is perfectly safe but _These _Names _Are _Hard
_To _Type.  Some of us prefer the simpler am29k and am29000.

So my questions are
1) Is our local expert right?
2) If so, will companies such as SUN, AT&T, DEC etc. predefine
   names such as _Sparc, _U3b2, _Vax in their ANSII C compilers?
   Note that doing so will also force change in some `existing
   practices'.

I also wonder about exactly where the user / implementer boundary
falls.  If the compiler vendor provides a system call library, is
it considered part of an implementation?  If so, will the system
calls have to be _Renamed?  This doesn't make sense to me.
Clearly, I am missing something here.

Thanks.

-- Bakul Shah (..!{ucbvax,sun}!amdcad!light!bvs)

PS:  Yes, I know the standard is not yet approved so there is no
     such thing as an ANSII compatible c compiler.  Perhaps I
     should've used dpANS tracking c compiler.

PPS: It would be neat if atleast the ANSII compilers were to
     follow a more regular predefine scheme, something like:

#define OS_TYPE                 unix
#define UNIX_TYPE               bsd4_3
#define MACHINE_TYPE            am29k
#define AM29K_TYPE              am29000
#define AM29000_VERSION         B

These are define hierarchies, starting with OS_TYPE and
MACHINE_TYPE, so that you can do things like

#if     OS_TYPE==<os>
# if    <OS>_TYPE==<os><version>
...
# endif
#endif

Once the standard is approved atleast some (and hopefully most)
system, software vendors will switch over to the standard
(meaning: make their c sources palatable to a conforming
compiler).  This would be a good time to do some simple cleanup.
But I am probably dreaming.
-- 
Bakul Shah

..!{ucbvax,sun}!amdcad!light!bvs

karl@haddock.ISC.COM (Karl Heuer) (02/19/88)

In article <1988Feb17.115402.12739@light.uucp> bvs@light.UUCP (Bakul Shah) writes:
>Now our local stdc expert says that [names like "am29k" are in the user's
>namespace].  He suggests that ANSII C compilers for the AMD29000 processor
>predefine _Am29k (for this family) and _Am29000 (for this specific
>processor).  [But these are hard to type.]

>So my questions are
>1) Is our local expert right?

Yes.

>2) If so, will companies such as SUN, AT&T, DEC etc. predefine
>   names such as _Sparc, _U3b2, _Vax in their ANSII C compilers?
>   Note that doing so will also force change in some `existing
>   practices'.

If they want them to be conforming compilers, they will change the predefined
names.  I doubt that mixed-case names like "_Vax" will be used; either "__vax"
or "_VAX" seems better to me.  Another proposal I've seen is to standardize
prefixes within this namespace, e.g. "__OS_unix" and "__MACH_vax".

>I also wonder about exactly where the user / implementer boundary
>falls.  If the compiler vendor provides a system call library, is
>it considered part of an implementation?  If so, will the system
>calls have to be _Renamed?  This doesn't make sense to me.
>Clearly, I am missing something here.

The proper way to provide a non-ANSI function like "fork" is to make an entry
point named "_fork" (single underscore is sufficient here; it's an external
identifier).  The system() function, which is part of the ANSI library, should
use this name: "pid = _fork();".  Thus, system() will work properly even if
the user's program has its own global object named "fork".

The implementation may now provide, for the user's use, an entry point named
"fork" which is equivalent$ to "_fork".  This function only gets linked if the
user uses it.

>PPS: It would be neat if atleast the ANSII compilers were to
>     follow a more regular predefine scheme, something like:
>
>#define OS_TYPE                 unix

But you can't say "#if OS_TYPE == unix", or anything equivalent to it, without
making substantial changes to the preprocessor.

Karl W. Z. Heuer (ima!haddock!karl or karl@haddock.isc.com), The Walking Lint
________
$ Such equivalence may be implemented by having fork() call _fork() as a
function, or a direct jump in assembly language, or by duplicating the code.
Even "#define fork _fork" might be legal, in a special <unix.h> header.

gwyn@brl-smoke.ARPA (Doug Gwyn ) (02/19/88)

In article <1988Feb17.115402.12739@light.uucp> bvs@light.UUCP (Bakul Shah) writes:
>1) Is our local expert right?

Yes.

>2) If so, will companies such as SUN, AT&T, DEC etc. predefine
>   names such as _Sparc, _U3b2, _Vax in their ANSII C compilers?

Possibly they will, or maybe they could get together and decide
on how to register the values of unofficial standard vendor macros
such as __CPU__, __OS__, etc. (which don't yet exist!)  This would
be useful, but was outside the scope of X3J11.

>If the compiler vendor provides a system call library, is
>it considered part of an implementation?  If so, will the system
>calls have to be _Renamed?

No, here's the situation.  The C library can contain all sorts of
vendor-specific stuff, POSIX additions, etc..  However, since
all normal (non leading-underscore) external names not named in
the [proposed] standard are guaranteed to be available for use by
applications, none of the implementations of library functions
named in the ANSI C standard is allowed to refer to such an extra
external name, nor to any other external name that could cause
linking with a module containing such an extension.  This means
that virtually all existing C libraries will need to be revised
so that, for example, fopen() does not call open() but instead
calls _open(), for example, where "_open" is not tied to "open"
in the library.  There can be a separate module in the library
containing "open" (which could just branch to _open), however,
so long as the ANSI C implementation does not depend on it.

scjones@sdrc.UUCP (Larry Jones) (02/19/88)

In article <1988Feb17.115402.12739@light.uucp>, bvs@light.uucp (Bakul Shah) writes:
< Now our local stdc expert says that an ANSII compatible compiler
< can not use these names [without leading underscores] as they
< belong to the name space reserved
< for the user.  Such a compiler may only predefine names that
< belong to the name space reserved for the implementer, that is,
< names matching the ``_[A-Z_][0-9A-Za-z_]*'' pattern.  He suggests
< that ANSII C compilers for the AMD29000 processor predefine _Am29k
< (for this family) and _Am29000 (for this specific processor).
< 
< So my questions are
< 1) Is our local expert right?

Yes.

< 2) If so, will companies such as SUN, AT&T, DEC etc. predefine
<    names such as _Sparc, _U3b2, _Vax in their ANSII C compilers?
<    Note that doing so will also force change in some `existing
<    practices'.

Hard to say for sure -- most of these companies have stated that they will
provide conforming compilers, but they may just have a switch that gets
rid of all the predefined identifiers rather than change them.  (Nothing
says a compiler must be conforming by default!)

< I also wonder about exactly where the user / implementer boundary
< falls.  If the compiler vendor provides a system call library, is
< it considered part of an implementation?  If so, will the system
< calls have to be _Renamed?  This doesn't make sense to me.
< Clearly, I am missing something here.

That depends on what you mean by "system call library".  An implementor is
free to provide additional library functions with any names at all.  HOWEVER,
none of the standard library routines can use them unless they start with
an underscore.  Thus, it's OK to have a routine in the library called (for
example) "read", but the standard library routine "fread" can't call it.
This doesn't necessarily mean that the system calls have to be renamed as
you can do some amazing magic with clever name mapping in the compiler,
interface libraries, etc.

< PPS: It would be neat if atleast the ANSII compilers were to
<      follow a more regular predefine scheme, something like:
< 
< #define OS_TYPE                 unix
< #define UNIX_TYPE               bsd4_3
< #define MACHINE_TYPE            am29k
< #define AM29K_TYPE              am29000
< #define AM29000_VERSION         B
< 
< These are define hierarchies, starting with OS_TYPE and
< MACHINE_TYPE, so that you can do things like
< 
< #if     OS_TYPE==<os>
< # if    <OS>_TYPE==<os><version>

Unfortunately, as soon as you have meta-symbols in the name (e.g. <OS>),
the poor user is out of luck again and can't use ANY name ending in
_TYPE or _VERSION since it MIGHT be defined as a macro!
-- 

----
Larry Jones                         UUCP: uunet!sdrc!scjones
SDRC                                MAIL: 2000 Eastman Dr., Milford, OH  45150
                                    AT&T: (513) 576-2070
"When all else fails, read the directions."

henry@utzoo.uucp (Henry Spencer) (02/21/88)

> Now our local stdc expert says that an ANSII compatible compiler
> can not use these names as they belong to the name space reserved
> for the user.  Such a compiler may only predefine names that
> belong to the name space reserved for the implementer, that is,
> names matching the ``_[A-Z_][0-9A-Za-z_]*'' pattern...
> 1) Is our local expert right?

Yes, although violation of this rule is listed as a "common extension" in
one of the appendixes (which are, note, not officially part of the standard).

> 2) If so, will companies such as SUN, AT&T, DEC etc. predefine
>    names such as _Sparc, _U3b2, _Vax in their ANSII C compilers?

Probably.

> I also wonder about exactly where the user / implementer boundary
> falls.  If the compiler vendor provides a system call library, is
> it considered part of an implementation?  If so, will the system
> calls have to be _Renamed?  This doesn't make sense to me.

Well, first note that the predefining rule cited by your local expert
applies specifically to *macros*, not necessarily to libraries.  Second,
while something like "open" clearly ought to be available under that
name, it would also be nice to have it available under some implementor-
reserved name like "__open" so that, say, "fopen" could call it without
requiring the user to avoid using "open" as the name of one of his own
functions.  This would greatly reduce the headache of having to remember
a large, growing, and machine-specific set of reserved names.  I think I
recall one of the earlier X3J11 drafts demanding that this be the case,
in fact, although I haven't finished reading the latest draft and can't
say whether such a rule is in there.  (Note, however, that the names of
the library functions actually defined in the standard *are* reserved --
along with a few general classes like str[a-z].* -- but at least that's
the same well-defined list for everyone.)
-- 
Those who do not understand Unix are |  Henry Spencer @ U of Toronto Zoology
condemned to reinvent it, poorly.    | {allegra,ihnp4,decvax,utai}!utzoo!henry

gnu@hoptoad.uucp (John Gilmore) (02/21/88)

< 2) If so, will companies such as SUN, AT&T, DEC etc. predefine
<    names such as _Sparc, _U3b2, _Vax in their ANSII C compilers?
<    Note that doing so will also force change in some `existing
<    practices'.

scjones@sdrc.UUCP (Larry Jones) wrote:
> Hard to say for sure -- most of these companies have stated that they will
> provide conforming compilers, but they may just have a switch that gets
> rid of all the predefined identifiers rather than change them.  (Nothing
> says a compiler must be conforming by default!)

In general, good companies tend to opt for "not pissing off their
existing customer base", and Sun in particular has stated that their
product will continue to compile their customers' existing 4.2BSD based
code without change, as they slide in Sys V and such.  (Of course,
buggy code is not always going to port.)  I don't think they have
made an explicit committment to ANSI C or POSIX.

The really relevant statement quoted here is "nothing says a compiler
must be conforming by default".  GCC is only "fully conforming" if you
use the "-ansi" switch (it even enables the loathsome trigraphs), but
they don't expect anyone to use the switch.  If you really want an
error message for everything in your program that wouldn't run on ANSI
C, you have to say "-pedantic", which at least can be used sort of
like "lint".

There is some faint hope that a conforming ANSI C program could get by
without #ifdef FOURTEEN_CHAR_FILENAMES and such, but personally I doubt
it.  There are too many systems with C and not all of them get
everything right, even when they agree on right, which most of them
don't.  As an example, a conforming program probably can't make *any*
assumptions about the format of file names...  Therefore I doubt many
programs will be fully conforming.  They will depend on some sort of
externally defined names to specify the environment they are to be run
in.  Some of the more "pedantic" folks might have their Makefiles
specify "-D__SYSV_TTYS" but they will probably just do "-DSYSV_TTYS"
like they always have.
-- 
{pyramid,ptsfa,amdahl,sun,ihnp4}!hoptoad!gnu			  gnu@toad.com
		"Watch me change my world..." -- Liquid Theatre

rbutterworth@watmath.waterloo.edu (Ray Butterworth) (02/22/88)

In article <1988Feb21.015424.20436@utzoo.uucp>, henry@utzoo.uucp (Henry Spencer) writes:
> while something like "open" clearly ought to be available under that
> name, it would also be nice to have it available under some implementor-
> reserved name like "__open" so that, say, "fopen" could call it without
> requiring the user to avoid using "open" as the name of one of his own
> functions.

Consider:

    #include <stdlib.h>
    #include <stdio.h>
    int open() { perror("open failed"); abort(); }
    main() { if (!fopen("xx", "r")) open(); }

Assuming I didn't make any typos, that is a correct ANSI program.
But if the ANSI fopen() uses my version of open(), it won't work
correctly.  That means the implementor of fopen() has introduced a
new reserved word, namely "open", that doesn't follow the ANSI rule
about leading underscores, and so the library is not a correct ANSI
library.

Thus the interface to the system requires something to prevent fopen()
from using my open(), and while there may be other more complicated
mechanisms, having the library use a name such as _open() internally
is obviously the simplest.

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()?

I am used to working on two different systems.  One of them uses
special entry points for all internal library calls, the other
uses no such special names.  The former would use the internal
name _putchar() in its implementation of perror(), the latter
would use the normal name putchar() in its perror().

From my point of view, the internal-name-for-everything approach
is clearly better, since a user that inadvertantly redefines an
ANSI function (especially one that won't be invented for a couple
of years yet) won't get an unpleasant surprise.  If the user
really does want to redefine a function that will be called by
the ANSI library functions, he is already doing something non=
portable and is making assumptions about how the library is
implemented.  In that case he probably already knows the internal
name of the function, and can just as easily redefine that one
instead.

I didn't see anything in the standard to indicate that either of
these behaviours is right or wrong.

gwyn@brl-smoke.ARPA (Doug Gwyn ) (02/22/88)

In article <4100@hoptoad.uucp> gnu@hoptoad.uucp (John Gilmore) writes:
>As an example, a conforming program probably can't make *any*
>assumptions about the format of file names...

Except for some minimal guarantee about header names.

Generally, file names will have to be provided by the environment,
best done either via compile-time macros or run-time command
arguments.

If you think about it, you'll realize that nothing can really BE
guaranteed.  For example, on UNIX one might think that "foo" is a
usable filename, but that depends on whether the current working
directory is writable, whether "foo" already exists, etc. which
is well beyond the scope of the C standard.

>Some of the more "pedantic" folks might have their Makefiles
>specify "-D__SYSV_TTYS" but they will probably just do "-DSYSV_TTYS"
>like they always have.

There is no need for an application to use _* macro names; that's
necessary only for stuff added to ANSI C by the implementation (in
order to avoid infringing on the names available for application use).

gwyn@brl-smoke.ARPA (Doug Gwyn ) (02/22/88)

In article <17033@watmath.waterloo.edu> rbutterworth@watmath.waterloo.edu (Ray Butterworth) writes:
>    #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()?

This wasn't a good example; putchar is a macro.  Even if you #undef it,
perror will not call a putchar function since it used the macro.

Assuming you change this to an example using strcmp(), for example,
then the answer is that your application does not conform to the
standard because it defines an external name that is reserved for
the implementation.

DISCLAIMER:  The above is my own personal interpretation of things.

scjones@sdrc.UUCP (Larry Jones) (02/23/88)

In article <17033@watmath.waterloo.edu>, rbutterworth@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.

----
Larry Jones                         UUCP: uunet!sdrc!scjones
SDRC                                MAIL: 2000 Eastman Dr., Milford, OH  45150
                                    AT&T: (513) 576-2070
"When all else fails, read the directions."

daveb@geac.UUCP (David Collier-Brown) (02/23/88)

In article <1988Feb21.015424.20436@utzoo.uucp>, henry@utzoo.uucp (Henry Spencer) writes:
> while something like "open" clearly ought to be available under that
> name, it would also be nice to have it available under some implementor-
> reserved name like "__open" so that, say, "fopen" could call it without
> requiring the user to avoid using "open" as the name of one of his own
> functions.

In article <17033@watmath.waterloo.edu> rbutterworth@watmath.waterloo.edu (Ray Butterworth) writes:
>     #include <stdlib.h>
>     #include <stdio.h>
>     int open() { perror("open failed"); abort(); }
>     main() { if (!fopen("xx", "r")) open(); }
> 
> Assuming I didn't make any typos, that is a correct ANSI program.
> But if the ANSI fopen() uses my version of open(), it won't work
> correctly.
[discussion elided]

  This is a serious, long-standing Unix-specific problem, inherited
without change by many unix-like and unix-derived systems....

> I am used to working on two different systems.  One of them uses
> special entry points for all internal library calls, the other
> uses no such special names....

  Sounds like the (Waterloo SDG) C compiler for God's Chosen Operating
System.

> 
> From my point of view, the internal-name-for-everything approach
> is clearly better, since a user that inadvertently redefines an
> ANSI function (especially one that won't be invented for a couple
> of years yet) won't get an unpleasant surprise. 
>
   That the developers of Unix didn't deal with this (known) problem
for their limited purposes is unfortunate.
   That subsequent developers, including Berkey and TellBellaphone
Sales, did not deal with it reflects strongly to their discredit.

 
> I didn't see anything in the standard to indicate that either of
> these behaviors is right or wrong.

  That the ANSI committee have chosen to ignore the problem is
understandable, under the circumstances.  It is also an admission of
incompetence and/or malfeasance, but that's a different discussion.

 --dave (history? we don't read history, we repeat it!) c-b
-- 
 David Collier-Brown.                 {mnetor yunexus utgpu}!geac!daveb
 Geac Computers International Inc.,   |  Computer Science loses its
 350 Steelcase Road,Markham, Ontario, |  memory (if not its mind) 
 CANADA, L3R 1B3 (416) 475-0525 x3279 |  every 6 months.

gwyn@brl-smoke.ARPA (Doug Gwyn ) (02/24/88)

In article <2317@geac.UUCP> daveb@geac.UUCP (David Collier-Brown) writes:
>  That the ANSI committee have chosen to ignore the problem is
>understandable, under the circumstances.  It is also an admission of
>incompetence and/or malfeasance, but that's a different discussion.

Far from ignoring the name space pollution problem, a conforming ANSI C
implementation is absolutely prohibited from infringing on the name
space reserved for the application, and a conforming application is
prohibited from preempting those names reserved for the implementation.

	"Each library function is declared in a header, whose
	contents are made available by the #include preprocessing
	directive.  The header declares a set of related functions,
	plus any necessary types and additional macros needed to
	facilitate their use.  Each header declares and defines only
	those identifiers listed in its associated section.  All
	external identifiers declared in any of the headers are
	reserved, whether or not the associated header is included.
	All external identifiers that begin with an underscore are
	reserved.  All other identifiers that begin with an
	underscore and either an upper-case letter or another
	underscore are reserved.  If the program defines an external
	identifier with the same name as a reserved external
	identifier, even in a semantically equivalent form, the
	behavior is undefined.

	The standard headers are:
		...
	If a file with the same name as one of the above < and >
	delimited sequences of characters, not provided as part of
	the implementation, is placed in any of the standard places
	for a source file to be included, the behavior is undefined."

Note that there is no prohibition against the implementation providing
additional external functions and data with identifiers NOT starting
with an underscore in its C library, so long as none of its ANSI C
support depends on them (because a conforming application is allowed
to use those names for its own external identifiers with different
semantics).  Additional system-specific headers can also be provided.
Note also that certain ranges of identifiers, such as SIG*, are
reserved for the implementation by the proposed standard.  Thus, a
conforming implementation must avoid using identifiers such as
	fopen	SIGMA	errno
for purposes other than those specified by the standard.  (SIGMA is
safe to use, however, if <signal.h> is not included.)

On the other hand, the proposed IEEE 1003.1, even with an attempt at
accommodating concerns expressed by X3J11 and at least two balloting
members concerning this issue, still does not adequately address the
problem.

What is this about "an admission of incompetence and/or malfeasance"?
Whose admission -- yours?

You know, it would be nice if people would at least READ the proposed
standard before publicly proclaiming what they think is wrong with it.

henry@utzoo.uucp (Henry Spencer) (02/25/88)

> You know, it would be nice if people would at least READ the proposed
> standard before publicly proclaiming what they think is wrong with it.

Don't flame him too loudly, Doug.  The crucial point here (implementations
not allowed to reserve other non-_ names) is an *EXTREMELY SUBTLE* result
of the wording in the current draft, so subtle that I can easily imagine
even a compiler implementor missing it entirely.  This badly needs at least
a footnote (and I intend to say so in my formal comments).
-- 
Those who do not understand Unix are |  Henry Spencer @ U of Toronto Zoology
condemned to reinvent it, poorly.    | {allegra,ihnp4,decvax,utai}!utzoo!henry

richard@aiva.ed.ac.uk (Richard Tobin) (02/26/88)

In article <1988Feb21.015424.20436@utzoo.uucp> henry@utzoo.uucp (Henry Spencer) writes:
>while something like "open" clearly ought to be available under that
>name, it would also be nice to have it available under some implementor-
>reserved name like "__open" so that, say, "fopen" could call it without
>requiring the user to avoid using "open" as the name of one of his own
>functions.  This would greatly reduce the headache of having to remember

It would also be nice if a user could easily replace the open() function
(for example) with one of their own that could call the original one.  But
in such a case the user might well want fopen() to call the new one, so
having __open available wouldn't help.  The desired effect can sometimes
be achieved by tricks when linking, but there doesn't seem to be a clean
way to do it.

-- Richard
-- 
Richard Tobin,                         JANET: R.Tobin@uk.ac.ed             
AI Applications Institute,             ARPA:  R.Tobin%uk.ac.ed@nss.cs.ucl.ac.uk
Edinburgh University.                  UUCP:  ...!ukc!ed.ac.uk!R.Tobin

gwyn@brl-smoke.ARPA (Doug Gwyn ) (02/26/88)

In article <1988Feb25.080434.29615@utzoo.uucp> henry@utzoo.uucp (Henry Spencer) writes:
>Don't flame him too loudly, Doug.  The crucial point here (implementations
>not allowed to reserve other non-_ names) is an *EXTREMELY SUBTLE* result
>of the wording in the current draft, so subtle that I can easily imagine
>even a compiler implementor missing it entirely.

Well, I'll let readers judge for themselves.  I posted the most relevant
draft proposed standard wording here; it sure didn't seem subtle to me.

Note that this has also been explained in this newsgroup and elsewhere
(for example, in journal articles by Plum and Jaeschke) many times previously.
It's not at all a recent development.

henry@utzoo.uucp (Henry Spencer) (02/28/88)

> >...  The crucial point here (implementations
> >not allowed to reserve other non-_ names) is an *EXTREMELY SUBTLE* result
> >of the wording...
> 
> Well, I'll let readers judge for themselves.  I posted the most relevant
> draft proposed standard wording here; it sure didn't seem subtle to me.

The problem is that the wording about strictly-conforming programs etc.
looks, at first glance, like definitions of terms -- NOT like an important
rule with significant impact on implementations.  Once you understand
that there is something significant to be found in those words, yes, it's
reasonably obvious.  But there is nothing in the standard proper to alert
you.  I am neither stupid nor unfamiliar with the X3J11 drafts (I have
read rather too many of them already...), and I missed it completely this
time until I ran into the name-space discussion in the Rationale and said,
"Wait a minute -- where did it guarantee that?".  It's an important result
of a section that looks like motherhoods plus definitions of terms.  All
that's needed is a footnote saying "note the implication that implementors
are not allowed to reserve names, except those allotted to them in 4.1.2".
-- 
Those who do not understand Unix are |  Henry Spencer @ U of Toronto Zoology
condemned to reinvent it, poorly.    | {allegra,ihnp4,decvax,utai}!utzoo!henry

gwyn@brl-smoke.ARPA (Doug Gwyn ) (02/28/88)

In article <1988Feb27.220901.8337@utzoo.uucp> henry@utzoo.uucp (Henry Spencer) writes:
>All that's needed is a footnote saying "note the implication that implementors
>are not allowed to reserve names, except those allotted to them in 4.1.2".

Our Redactor (draft standard editor) generally doesn't seem too happy about
littering the body of the standard itself with footnotes, preferring to leave
most of the explanatory stuff to the Rationale document.  However, we've
added some such footnotes before, so your request would not be without
precedent.

daveb@geac.UUCP (David Collier-Brown) (02/29/88)

In article <2317@geac.UUCP> daveb@geac.UUCP (David Collier-Brown) writes:
||   That the ANSI committee have chosen to ignore the problem is
|| understandable, under the circumstances.  It is also an admission of
|| incompetence and/or malfeasance, but that's a different discussion.

In article <7332@brl-smoke.ARPA> gwyn@brl.arpa (Doug Gwyn (VLD/VMB) <gwyn>) writes:
| Far from ignoring the name space pollution problem, a conforming ANSI C
| implementation is absolutely prohibited from infringing on the name
| space reserved for the application, and a conforming application is
| prohibited from preempting those names reserved for the implementation.

  Please note that this is **not** the subject being discussed
previously, but a reasonable work-around for it.  I use the same
workaround.
  That does not make it a solution.  In fact, its presence indicates
that the solution is either unacceptable or undesirable. And that's
what I'm accusing the committee of. (That's the different
discussion, you see.)

 --dave (Yeah, I read it.  It's often pretty good, but...) c-b
-- 
 David Collier-Brown.                 {mnetor yunexus utgpu}!geac!daveb
 Geac Computers International Inc.,   |  Computer Science loses its
 350 Steelcase Road,Markham, Ontario, |  memory (if not its mind) 
 CANADA, L3R 1B3 (416) 475-0525 x3279 |  every 6 months.

am@cl.cam.ac.uk (Alan Mycroft) (03/01/88)

In article <1988Feb21.015424.20436@utzoo.uucp> henry@utzoo.uucp (Henry Spencer) writes:
>> 2) If so, will companies such as SUN, AT&T, DEC etc. predefine
>>    names such as _Sparc, _U3b2, _Vax in their ANSII C compilers?
>
>Probably.
>
It would probably make a great deal of sense if the dpANS rationale
would SUGGEST formats for these things to be encoded.
For example, an indication that __cc_*, __mc_*, __os_*
might specify respectively compiler, machine, operating system
would be very helpful both for knowing what sort of names to look for
(and for making code easier to read) and a good guide to implementors:
E.g. On the xyzzy system we might have predefined
  __cc_gnu  __mc_m68000  __os_unix
This would be a much better alternative than the present trend which seems to
be that compilers continue to predefine "unix", "m68000" and the like
(and so be non-conforming)
and then provide a switch (-Uunix -Um68000) to give an ANSI compiler!!!

gwyn@brl-smoke.ARPA (Doug Gwyn ) (03/02/88)

In article <265@aiva.ed.ac.uk> richard@uk.ac.ed.aiva (Richard Tobin) writes:
>It would also be nice if a user could easily replace the open() function
>(for example) with one of their own that could call the original one.

I disagree strongly with this.  The application writer has no way of knowing
what the specific internal library semantics are, making it likely that his
meddling would break the behavior of some of the standard library routines.

For example, my System V emulation package on a BRL/JHU PDP-11 UNIX kept
track of open file descriptors internally.  Interception of _open() by an
application that was unaware of this could have led to erroneous operation.

gak@mhuxm.UUCP (Vincent Hatem) (03/03/88)

In article <7387@brl-smoke.ARPA>, gwyn@brl-smoke.UUCP writes:
> In article <265@aiva.ed.ac.uk> richard@uk.ac.ed.aiva (Richard Tobin) writes:
> >It would also be nice if a user could easily replace the open() function
> >(for example) with one of their own that could call the original one.
> 
> I disagree strongly with this.  The application writer has no way of knowing
> what the specific internal library semantics are, making it likely that his
> meddling would break the behavior of some of the standard library routines.
> 
> For example, my System V emulation package on a BRL/JHU PDP-11 UNIX kept
> track of open file descriptors internally.  Interception of _open() by an
> application that was unaware of this could have led to erroneous operation.

Once upon a time (not long ago) I re-wrote (not alone) the link library for
Modula-2 on the Sun. We were writing a system in M2 and needed to have a truely
*portable* library. 

Anyway, I thought that Modula-2's ability to re-use function names *very* 
useful. By changing the IMPORT statement, you could change the I/O system
that you were using. By using an Object-Oriented Modular design in the library,
you could NOT mix implementations - each module contains a complete set of 
functions to act upon the file object - ie: open(), close(), read(), write().
Since you cannot include unqualified IMPORTs of two modules containing the
same function names, the problem of getting the wrong read() is nonexistant.

Since the higher-level functions (functions such as printf()) eventually use
read/write, etc., and all the modules use the same parameters for the same 
functions (ie: the open() in every module takes the same parameters), the 
functions (modules) may be interchanged.

I think that C could learn a lot from Modula-2. It may look like Pascal, but
you can do things in Modula-2 that you can't even do in C! (such as set your
registers without resorting to assembler, among others)

-- 
Vincent Hatem
AT&T International, International Systems Operations, UNIX Technical Support
                        Telefon: (201) 953-8030
		Please send all e-mail to: ihnp4!atti01!vch

terry@wsccs.UUCP (terry) (03/12/88)

In article <229@sdrc.UUCP>, scjones@sdrc.UUCP (Larry Jones) writes:
> In article <17033@watmath.waterloo.edu>, rbutterworth@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@wsccs

chris@mimsy.UUCP (Chris Torek) (03/15/88)

In article <302@wsccs.UUCP> terry@wsccs.UUCP (terry) writes:
>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.

This is, I think, naive.  A number of vendors are fanatically tracking
the dpANS even now.  4BSD may be slow to follow (as in `you will have
to wait for 4.4BSD to have even a faint hope of seeing an
ANS-conforming compiler' [well, you can try GNU CC in the interim]),
and I believe some vendors will provide two flavours of C (to work
around the botches[1] in the standard until everyone can change their
code), but the standard looks very real.

-----
[1] E.g., widening rules for unsigned (yes, I am going to harp on that
one forever).
-----

As an aside, terry asks us to run the following to see why, he believes,
people need to write their own `printf' functions, spurning those in
the supplied libraries:

>	#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).

True.  Some might even catch your bugs at compile time!  If
you do that, all bets are off, just as if you do *this*:

	main()
	{
		float f;
		int *p = (int *)&f;

		*p = 0x00008000;
		printf("%g\n", f);
		exit(0);
	}

Run it on a Vax and you will get `Illegal instruction (core dumped)',
because the bit pattern 0x00008000 is reserved and is an illegal float.

Note that the line

	printf(NULL);

contains two bugs.  First, it should be

	printf((char *)NULL);

and second, printf is not supposed to be passed (char *)NULL.
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)
Domain:	chris@mimsy.umd.edu	Path:	uunet!mimsy!chris

scjones@sdrc.UUCP (Larry Jones) (03/16/88)

In article <302@wsccs.UUCP>, terry@wsccs.UUCP (terry) writes:
> In article <229@sdrc.UUCP>, scjones@sdrc.UUCP (Larry Jones) writes:
> > In article <17033@watmath.waterloo.edu>, rbutterworth@watmath.waterloo.edu (Ray Butterworth) writes:
[discussion on redefining library functions culminating in the observation that
it usually works]
> 
> 	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.  

Well, how fortunate you are.  Try redefining putchar() like in Ray's original
example some time.  When the preprocessor does macro substitution on your
function definition you'll get some really interesting error messages.  As
compilers get smarter you're going to have more and more problems with this
kind of stuff and some of it can be really hairy to track down.  As an example,
we have our own version of the memory allocation functions (malloc, realloc,
etc.) that we use for debugging - when we got a new release of the library,
we discovered that if you opened a particular type of file and did a particular
sequence of operations, the program would bomb.  Turned out that an obscure
piece of the I/O library was using the block header on the file buffer (which
was know to have been malloc'ed) to determine its length.  The header format
had been changed and our routines were still using the old format.

> 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.  

Sure, just take your ball and go home.  Just be sure not to complain about
vendors who tell you to go read the standard and refuse to change.  Also,
don't complain about the compile, link, and execution speed on those
machines that work like you want.

> 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.  

Say what?  If X3J11 hadn't bothered to standardize the libraries they would
have been done a couple years ago.  The libraries ARE standard.

> 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).

You get similar behaviour from things like:
    *(char *)0 = 5;
The cause is the same - your program is WRONG.  Read the draft standard and
follow it and you won't have these problems.

> 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.

AT&T has stated they will provide an ANSI compiler and the POSIX standard
requires one.  I doubt that many vendors will supply one compiler and use
a different one to compile the OS.  If K&R is all you need, complete with its
ambiguities, conflicts, and errors, then just go bury your head in the sand
and forget about portability.  No one's going to want what you're doing anyway.

----
Larry Jones                         UUCP: uunet!sdrc!scjones
SDRC                                MAIL: 2000 Eastman Dr., Milford, OH  45150
                                    AT&T: (513) 576-2070
"When all else fails, read the directions."

henry@utzoo.uucp (Henry Spencer) (03/17/88)

> ... 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...

Remember that (a) not all implementations are compilers followed by linkers
and (b) at least some implementations will permit redefining system names
but those redefinitions will *not* affect the actions of other system
functions, which will be calling the supposedly-redefined functions under
other, secret names.
-- 
Those who do not understand Unix are |  Henry Spencer @ U of Toronto Zoology
condemned to reinvent it, poorly.    | {allegra,ihnp4,decvax,utai}!utzoo!henry

gwyn@brl-smoke.ARPA (Doug Gwyn ) (03/19/88)

In article <302@wsccs.UUCP> terry@wsccs.UUCP (terry) writes:
>	In specifying either behavior, the draft would have to dictate the
>actions of the linker.

"This happens not to be the case."  The (proposed) standard specifies a
"treaty point" between the application and the implementation.  Violation
of the treaty has "random" consequences including occasionally being able
to get away with it.  But the prudent programmer will follow the rules.

>This means that in 99% of the cases, your putchar would be used.

Except that putchar is a macro, so yours wouldn't be used after all.
To make this a reasonable dicsussion, use fputc() or some other
function that MIGHT be used by the C library implementation.

>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.

Ha, if C were "standard", we wouldn't have had to spend years figuring
out a standard for it.  X3J11 early on realized that a significant
amount of the C library also needed to be standardized.  It would be
stupid to perpetuate the idea that every application needs to carry
around its own implementation of the C library.

>For example, get 5 UNIX machines,
>of any flavor, and compile and run the following fragment:
>		printf( NULL);

So systems do different random things when you violate the interface
specs.  So what?

>I don't believe everybody will rewrite their UNIX in ANSI C, anyway...

No, it's being redone in C++.  That's totally irrelevant.

terry@wsccs.UUCP (terry) (03/24/88)

In article <302@wsccs.UUCP> I write:
>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.

In article <10646@mimsy.UUCP>, Chris Torek replies:
> This is, I think, naive.  A number of vendors are fanatically tracking
> the dpANS even now.  4BSD may be slow to follow (as in `you will have
> to wait for 4.4BSD to have even a faint hope of seeing an
> ANS-conforming compiler' [well, you can try GNU CC in the interim]),

A great deal of developers in the real world like their code to compile and
don't like to change it (thus possibly introducing errors) once it does.
That means that with the current volume of code out there, there is a *LOT*
of inertia against the ANSI standard.  I think you will find "GNU C" conforms
to the proposed ANSI standard, since there isn't a real one yet.  I may not
even do that, after the recent changes.

> and I believe some vendors will provide two flavours of C (to work
> around the botches[1] in the standard until everyone can change their
> code), but the standard looks very real.
> -----
> [1] E.g., widening rules for unsigned (yes, I am going to harp on that
> one forever).

This may be the case, but I will hold off on prototyping until all the machines
I want to run on or that I may (or may not) want to run on in the future
support prototyping.

I think a better target for standardization would be system libraries and
executable file formats.  I think it would be nifty to be able "port" a program
by simply having the converter "know" what a system call looks like on a
certain machine and translating only the specific assembly instructions.  I
have seen such a program move an object file from an NCR tower to a Xenix
system.  Admittedly, with current vendor specific code files, this would only
work on simpler programs.  Wouldn't it be nice if there were only one UNIX
kernal (eventually), given that optimization is not sacraficed in the
conversion (Intel <=> Motorolla would probably be a sacrafice).  I think that
this goal is a long way off; ioctl() doesn't even work uniformly from one UNIX
(BSD) implimentation to another.  It would be nice if all I had to do to port
from a BSD to a SysV machine with a 680x0 was tar a tape.

> As an aside, terry asks us to run the following to see why, he believes,
> people need to write their own `printf' functions, spurning those in
> the supplied libraries:
> 
> >	#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).
> 
> True.  Some might even catch your bugs at compile time!

And some won't.  My point in a nutshell.

> If you do that, all bets are off, just as if you do *this*:

[core dump fodder deleted]

> Note that the line
> 
> 	printf(NULL);
> 
> contains two bugs.  First, it should be
> 
> 	printf((char *)NULL);

I believe I #defined NULL that way...

> 
> and second, printf is not supposed to be passed (char *)NULL.

And how do you debug it in a recoverable fashion so that you know it is going
to happen?  Besides, you don't release a product with a function which is not
written the same from system to system, unless you have source and agree with
each implimentation, and they agree with each other (they don't).  printf()
was simply a handy example.


| Terry Lambert           UUCP: ...{ decvax, ihnp4 }                          |
| @ Century Software          : ...utah-cs!uplherc!sp7040!obie!wsccs!terry    |
| SLC, Utah                                                                   |
|                   These opinions are not my companies, but if you find them |
|                   useful, send a $20.00 donation to Brisbane Australia...   |
| 'The ink is black; the page is white; Only K & R wrote C right...'          |

terry@wsccs.UUCP (terry) (03/25/88)

In article <242@sdrc.UUCP>, scjones@sdrc.UUCP (Larry Jones) writes:
> In article <302@wsccs.UUCP>, I wrote:
> [discussion on redefining library functions culminating in the observation
> that it usually works]
> > 
> > 	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.  
> 
> Well, how fortunate you are.  Try redefining putchar() like in Ray's original
> example some time.

	Please look at your synopsis and note that it refers to 'redefinition
of library functions'... then note that putchar() is not a library function,
that it is defined in stdio.h [#define putchar(x) putc(x,stdout)], and that it
is possible to redefine it by '#undef'ing it first.

> When the preprocessor does macro substitution on your function definition
> you'll get some really interesting error messages.

If I were so naieve as to think the _linker_ handled preprocessor statements.

> As compilers get smarter you're going to have more and more problems with
> this kind of stuff and some of it can be really hairy to track down.

Enlighten me.  How is absolutely reserving things in addition to the current
reserved word list 'smarter'?

> As an example, we have our own version of the memory allocation functions
> (malloc, realloc, etc.) that we use for debugging - when we got a new
> release of the library, we discovered that if you opened a particular type
> of file and did a particular sequence of operations, the program would bomb.
> Turned out that an obscure piece of the I/O library was using the block
> header on the file buffer (which was know to have been malloc'ed) to
> determine its length.  The header format had been changed and our routines
> were still using the old format.

Block header?  You mean 'struct mallinfo'?  That is why you are supposed to
[#include <malloc.h>].  Certainly you can't mean that you had a problem due
to a change in [struct file] in <sys/file.h>?  Were you malloc'ing memory
from a file?

I wrote:
> 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.  

Larry replied:
> Sure, just take your ball and go home.

No, take my _w_a_l_l_e_t and go elsewhere.

> Just be sure not to complain about vendors who tell you to go read the
> standard and refuse to change.

Oh.  You have anyone specific in mind?  IBM, DEC?

> Also, don't complain about the compile, link, and execution speed on those
> machines that work like you want.

"Anything that works is better than anything that doesn't"

Besides, the K&R compiler on the CRAY runs _much_ faster than the ANSI
compiler it doesn't have :-).

> > 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.  
> 
> Say what?  If X3J11 hadn't bothered to standardize the libraries they would
> have been done a couple years ago.  The libraries ARE standard.

Ok.  What is the "standard" ioctl() call to make a BSD system, a SysV system,
an MS-DOS system, and a VMS system put the terminal into "raw" mode so I can
port my MicroEMACS?  WHAT!?!  I have to call it with different parameters for
BSD and SysV?!?  I have to make SYS$QIO(p1, p2... p12); calls on VMS?  I have
to call ASSEMBLY on MS-DOS?  I thought you told me these libraries for C were
_s_t_a_n_d_a_r_d!

What do you mean that "curses doesn't work right with AM terminals"?

> 
> > 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).
> 
> You get similar behaviour from things like:
>     *(char *)0 = 5;
> The cause is the same - your program is WRONG.

Of course it's wrong!  That's the whole point!  What if I have a bug in my
LISP interpreter that passes a null to printf if it recurses *exactly* 57
times through a routine?

The whole point is, you can't get perfectly error-free code when you depend on
library routines written by some kid at Berkley who is getting paid workstudy
wages by a cognitive psychologist so he doesn't have to fry hamburgers to pay
for his dorm room.

The 'printf()' function was only an _example_, not of goood code, but of code
that acts OK on 14 out of 15 machines and core dumps on the 15th.

> Read the draft standard and follow it and you won't have these problems.

Ah yes.  I see that you, like me, write code that never needs to be run through
a debug routines ;-).  The problem with the "draft standard" is that it is not
necessarily backward compatable.  I am not against a more rigorous compiler,
simply against a language standard that 1) is _still_ amorphorus, and 2) allows
or requires someone to write code that won't run on another machine.  Port the
VMS version of moria (in pascal) to Turbo Pascal IV... "both comply with the
ANSI standard, it'll work, no problem". RIGHT.

I said:
> 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.

OK, maybe it won't go away.  But it should.

> AT&T has stated they will provide an ANSI compiler and the POSIX standard
> requires one.

The 'POSIX standard'?  When either an 'ANSI standard C' or a 'POSIX standard'
exist in immutable form, I might be inclined to agree with you... By the way,
when did AT&T say that?

> I doubt that many vendors will supply one compiler and use a different one
> to compile the OS.

Agreed... which is why I think an ANSI standard will have a long ways to go
to gain acceptance.  Of course, we may be wrong... I know of at least one UNIX
that is currently being written in Modula2.

> If K&R is all you need, complete with its ambiguities, conflicts, and errors,
> then just go bury your head in the sand and forget about portability.  No
> one's going to want what you're doing anyway.

It's _NOT_ all I need!  Far from it!  But it runs on more machines than a
currently non-accepted "standard" which still has to be accepted.  As long as
there are more machines running K&R, I will program K&R... unless I'm paid to
program something else :-).

Your arguments remind me of the programmer who would only program in this
obscure language called IBM/JCL, convinced that his programs would someday
run on all machines, as the other vendors "came to their senses".


| Terry Lambert           UUCP: ...{ decvax, ihnp4 }                          |
| @ Century Software          : ...utah-cs!uplherc!sp7040!obie!wsccs!terry    |
| SLC, Utah                                                                   |
|                   These opinions are not my companies, but if you find them |
|                   useful, send a $20.00 donation to Brisbane Australia...   |
| 'There are monkey boys in the facility.  Do not be alarmed; you are secure' |

karl@haddock.ISC.COM (Karl Heuer) (03/30/88)

The story so far: Terry observes that redefining a library function usually
works, and asserts that it works on all known machines.  Larry points out that
it doesn't produce the correct behavior for putchar(), as in the original
example.  Now in article <378@wsccs.UUCP> terry@wsccs.UUCP (terry) writes:

>Please look at your synopsis and note that it refers to 'redefinition
>of library functions'... then note that putchar() is not a library function,
>[but a macro], and that it is possible to redefine it by '#undef'ing it first.

But (on most UNIX systems) that does not "redefine" the routine in the sense
that other units, like printf, will suddenly start using yours instead of the
real one.  Moreover, not all systems implement putchar() as a macro.  If you
try to redefine *any* standard routine -- whether macro or function -- the
result should be, and is, undefined.  Why should the user be forced to learn
the implementation details?

>>As compilers get smarter you're going to have more and more problems with
>>this kind of stuff and some of it can be really hairy to track down.
>
>Enlighten me.  How is absolutely reserving things in addition to the current
>reserved word list 'smarter'?

It allows better optimization.  E.g., inlining of the <string.h> functions.

>>>For example, get 5 UNIX machines, [and try printf(NULL)]
>>your program is WRONG.
>Of course it's wrong!  That's the whole point!

I don't get it.  What do you think *should* happen if you pass a NULL pointer
(appropriately cast) to printf()?

>[I am] against a language standard that ... allows or requires someone to
>write code that won't run on another machine.

No useful language can disallow this; see HAKMEM item #154.  If the dpANS
*requires* it, I'm sure the X3J11 committee would like to hear it.

Karl W. Z. Heuer (ima!haddock!karl or karl@haddock.isc.com), The Walking Lint

rcvie@tuvie (ELIN Forsch.z.) (03/31/88)

In article <3225@haddock.ISC.COM> karl@haddock.ima.isc.com (Karl Heuer) writes:
>Moreover, not all systems implement putchar() as a macro.  If you
>try to redefine *any* standard routine -- whether macro or function -- the
>result should be, and is, undefined.  Why should the user be forced to learn
>the implementation details?

Just try the portable way and noone has to learn anything but that there
*are* some routines implemented as functions and some as macros:

#ifdef putchar
#undef putchar

<your putchar-macro/function>

		Dietmar Weickert,
			ALCATEL-ELIN Research Center, Vienna, Austria.

karl@haddock.ISC.COM (Karl Heuer) (04/01/88)

In article <598@tuvie> rcvie@tuvie.UUCP (Alcatel-ELIN Forsch.z.) writes:
|In article <3225@haddock.ISC.COM> karl@haddock.ima.isc.com (Karl Heuer) writes:
|>If you try to redefine *any* standard routine -- whether macro or function
|>-- the result should be, and is, undefined.  Why should the user be forced
|>to learn the implementation details?
|
|Just try the portable way and noone has to learn anything but that there
|*are* some routines implemented as functions and some as macros:
|  #undef putchar
|  <your putchar-macro/function>

That isn't portable.  After you've redefined something, you have no way of
knowing whether other library routines (e.g. puts) will be using your putchar
or the standard one.

Karl W. Z. Heuer (ima!haddock!karl or karl@haddock.isc.com), The Walking Lint

markb@sdcrdcf.UUCP (Mark Biggar) (04/02/88)

In article <3264@haddock.ISC.COM> karl@haddock.ima.isc.com (Karl Heuer) writes:
|In article <598@tuvie> rcvie@tuvie.UUCP (Alcatel-ELIN Forsch.z.) writes:
||In article <3225@haddock.ISC.COM> karl@haddock.ima.isc.com (Karl Heuer) writes:
||>If you try to redefine *any* standard routine -- whether macro or function
||>-- the result should be, and is, undefined.  Why should the user be forced
||>to learn the implementation details?
||Just try the portable way and noone has to learn anything but that there
||*are* some routines implemented as functions and some as macros:
||  #undef putchar
||  <your putchar-macro/function>
|That isn't portable.  After you've redefined something, you have no way of
|knowing whether other library routines (e.g. puts) will be using your putchar
|or the standard one.
I thought the standard included a guarantee that if you did the above that
the libraries would still continue to use the original definition.
In fact the whole reason for the necessity of using the #undef etc. was to
allow for that guarantee.

Mark Biggar
{allegra,burdvax,cbosgd,hplabs,ihnp4,akgua,sdcsvax}!sdcrdcf!markb
markb@rdcf.sm.unisys.com

karl@haddock.ISC.COM (Karl Heuer) (04/02/88)

In article <5202@sdcrdcf.UUCP> markb@sdcrdcf.UUCP (Mark Biggar) writes:
>In article <3264@haddock.ISC.COM> karl@haddock.ima.isc.com (Karl Heuer) writes:
>>That isn't portable.  After you've redefined something, you have no way of
>>knowing whether other library routines (e.g. puts) will be using your
>>putchar or the standard one.
>
>I thought the standard included a guarantee that if you did the above that
>the libraries would still continue to use the original definition.
>In fact the whole reason for the necessity of using the #undef etc. was to
>allow for that guarantee.

No, it's guaranteed that the libraries will not depend on NON-standard
functions (e.g. you can safely use "open" without worrying that "fopen" calls
a function of that name), but the names of the standard routines are reserved.

(Note: "putchar" is a bad example, because it happens to work in the usual
implementation.  But "malloc" does not, and neither does "putc".)

Karl W. Z. Heuer (ima!haddock!karl or karl@haddock.isc.com), The Walking Lint