[comp.lang.c] Questions on X3J11 draft

lvc@danews.ATT.COM (Larry Cipriani) (12/03/86)

I've questions about the X3J11 draft.  I don't have a copy so
could someone answer these for me.  Thanks a lot.

1) What is the unary plus operator I've heard ?  Is it an attempt
to force ordering in expression evaluation ?  If it is I strongly 
object to this, it doesn't seem necessary as any expression can
be split up and its parts can be evaluated separately.  From a
human factors approach it is grotesque.

2) Can I do something like this:

#define ABC=100

or must the = be omitted ?

3) Can I do something like this:

char a[sizeof(struct name *)0->element];

If not, how can I get the size of a structure element without
defining an object of the structure type (sometimes you don't
need the object)?  (Is this even valid C ?).

A couple points on strategy:

4) Are there provisions for future modifications to the standard?
Experience may show an idea that looks fine in the draft may
turn out to be a mistake.  If there isn't any way to back
out mistakes I'm registering a complaint on it.

5) Has any attempt been made to see what percentage of existing
code (say at AT&T or wherever) would break under the X3J11 draft?
If not, I believe it would be useful to determine that.  If
95% of existing code will break perhaps the draft ought to be
revised.  If that much code will break, people aren't going to
program in the language.  They'll keep using the compilers that exist.

6) On a more philosophical note, I object to the use of the name
C for the language.  Unless Dennis Ritchie has said he doesn't
mind, I'll say it;  call it something else, say C87 (like FORTRAN77).

Thanks again,

Larry Cipriani
cbsck!lvc
-- 

Larry Cipriani	AT&T Network Systems
danews!lvc

henry@utzoo.UUCP (Henry Spencer) (12/04/86)

> 1) What is the unary plus operator I've heard ?  Is it an attempt
> to force ordering in expression evaluation ? ...

Unary plus was introduced originally, as I understand it, for various
minor reasons.  (For example, "+204" is a valid number when read by
printf, but is illegal in a [pre-X3J11] C program, which seems undesirable.)
It has since been overloaded as an optimization fence, which I'm not keen
on.  I can see the desirability of such a fence; splitting up expressions
and evaluating the pieces separately can be a major pain, and makes code
much harder to read.  I can't say as I like unary plus as the syntax for
the fence, though.

> 2) Can I do something like this:
> 
> #define ABC=100

No, not with the semantics you obviously are thinking of.  Why would you
want to?  That is not C, and never has been.  It might perhaps be the right
way to do it if one were designing a new language, but that's not the issue
at hand.

> 3) Can I do something like this:
> 
> char a[sizeof(struct name *)0->element];

Don't think so.  Have you considered determining the type of "element" and
saying "char a[sizeof(the_type)]"?  It is agreed that this would be a bit
simpler with a "typeof" operator, but it's not a disaster even so; at worst
it means an extra macro or typedef to give the type a name of its own.

> 4) Are there provisions for future modifications to the standard?

I believe all ANSI standards have provisions for future review.  The people
who do these things are not idiots.

> 5) Has any attempt been made to see what percentage of existing
> code (say at AT&T or wherever) would break under the X3J11 draft?

I suspect AT&T has been paying close attention to this, although I don't
know of any actual numbers.  The intent all along has been that existing
*legal* code will not break.

> 6) On a more philosophical note, I object to the use of the name
> C for the language.  Unless Dennis Ritchie has said he doesn't
> mind...

Dennis has been involved with X3J11, although not deeply; last I heard,
he approved.  I know he liked the idea of someone else taking over the
role of ultimate authority on C.
-- 
				Henry Spencer @ U of Toronto Zoology
				{allegra,ihnp4,decvax,pyramid}!utzoo!henry

rbutterworth@watmath.UUCP (12/05/86)

> > 5) Has any attempt been made to see what percentage of existing
> > code (say at AT&T or wherever) would break under the X3J11 draft?
> I suspect AT&T has been paying close attention to this, although I don't
> know of any actual numbers.  The intent all along has been that existing
> *legal* code will not break.

I can think of a perfectly conforming ANSI compiler that will break
almost any existing C code.  Imagine a piece of code such as the following:
    #include <stdio.h>
    {
        extern int getchar();
        auto int c;
        c=getchar();
At the moment, this will blow up on (all?) existing C compilers since
"getchar" is a macro.  Of course everyone KNOWS this and so never puts
such things into their code.  But under ANSI, almost any function can
be defined as a macro in the header files.  That means that almost
any program that contains an "extern type libCfunc();" in it can
potentially break under a conforming ANSI compiler.

This change may or may not be a good thing; I don't know.
I do know that my own coding style has changed drastically
because of it.  I used to put explicit extern statements for
all the functions I use, simply to document the fact that I
am using them.  Now I NEVER put extern statements into ANY
source.c file.

henry@utzoo.UUCP (Henry Spencer) (12/05/86)

> ...  (For example, "+204" is a valid number when read by printf...

Oops, obviously that should have been "scanf"!
-- 
				Henry Spencer @ U of Toronto Zoology
				{allegra,ihnp4,decvax,pyramid}!utzoo!henry

philip@axis.UUCP (Philip Peake) (12/07/86)

In article <3800@watmath.UUCP> rbutterworth@watmath.UUCP writes:
>
>I can think of a perfectly conforming ANSI compiler that will break
>almost any existing C code.  Imagine a piece of code such as the following:
>    #include <stdio.h>
>    {
>        extern int getchar();
>        auto int c;
>        c=getchar();
>At the moment, this will blow up on (all?) existing C compilers since
>"getchar" is a macro.  Of course everyone KNOWS this and so never puts
>such things into their code.  But under ANSI, almost any function can
>be defined as a macro in the header files.  That means that almost
>any program that contains an "extern type libCfunc();" in it can
>potentially break under a conforming ANSI compiler.
>
>This change may or may not be a good thing; I don't know.
>I do know that my own coding style has changed drastically
>because of it.  I used to put explicit extern statements for
>all the functions I use, simply to document the fact that I
>am using them.  Now I NEVER put extern statements into ANY
>source.c file.

This is a *very* good point ! (Why didn't I think of it ? ......)

My personal coding style has changed considerably over the years, and
one of the directions in which it evolved was to ALWAYS put extern
declarations of any functions that I use. 

I started by putting them into a header file, this gets to be a pain,
since we either have a header file for each C file, or lots of redundant
extern declarations, and 'make' going beserk if you change one of the
declarations.

I now put them into the C file - I think its cleaner, and I like to be able
to find the type of a function when I am looking at a piece of code.

Taking the above example (sligthly modified), what if the function
actually returns something other than int ?

You HAVE to put the extern definition, if not other things will
probably (certainly ?) break.

How can I know, when trying to write portable code, if the 'library'
function I am going to use is a real function or a macro ?

Philip

rbutterworth@watmath.UUCP (Ray Butterworth) (12/08/86)

In article <775@axis.UUCP>, philip@axis.UUCP (Philip Peake) writes:
> In article <3800@watmath.UUCP> rbutterworth@watmath.UUCP writes:
> >                          But under ANSI, almost any function can
> >be defined as a macro in the header files.  That means that almost
> >any program that contains an "extern type libCfunc();" in it can
> >potentially break under a conforming ANSI compiler.
> This is a *very* good point ! (Why didn't I think of it ? ......)
I didn't think of it either.  I was hit over the head with it when
I tried to port a program to a compiler that is trying to conform
to ANSI's moving target.  It had several functions defined as macros
to call other functions in their existing library of non-ANSI functions.

> Taking the above example (sligtly modified), what if the function
> actually returns something other than int ?
> You HAVE to put the extern definition, if not other things will
> probably (certainly ?) break.
Each function has an associated header file (one file may describe
many functions) that contains its external prototype definition, and
possibly a macro defining the function.  If you do not include that
header file, you must put in the explicit external prototype yourself.
It can be very awkward to do if that is what you really want (e.g.
if you want your own external prototype for printf() you cannot include
stdio.h, or any other header file that might include that one).
If, however, you always use the header files, everything is taken
care of automatically and you never need to use an explicit extern
statement (and in fact you might get into trouble if you do).

> How can I know, when trying to write portable code, if the 'library'
> function I am going to use is a real function or a macro ?
Normally it shouldn't matter to you whether you are actually getting
a macro or a function.  On those occasions where you really do want
to get a function and not a macro, you can do one of two things.
Either put "#undef FunctionName" in the source immediately before
you use it (this gets rid of the possibility of using the macro,
and the header file should still contain the external prototype
and the library should contain a real function version of the function)
Or, you can call the function as "(FunctionName)(args)".  The extra
parentheses stop it from looking like a macro invocation.  The advantage
to this second method is that you can still get the macro version
later on in the source file; you can't if you use #undef.  (I think
that the latest version of ANSI still allows this second method, but
I don't guarantee it.)
Of course if a function cannot be implemented as a macro without
causing side effects on its arguments (i.e. each argument must be
evaluated exactly once), then that function is not allowed to be
implemented as a macro.

For compatibility with past mistakes, a few functions such as
getchar() are explicitly allowed to violate the above rule.

markb@sdcrdcf.UUCP (Mark Biggar) (12/09/86)

In article <775@axis.UUCP> philip@axis.UUCP (Philip Peake) writes:
>In article <3800@watmath.UUCP> rbutterworth@watmath.UUCP writes:
>>I can think of a perfectly conforming ANSI compiler that will break
>>almost any existing C code.  Imagine a piece of code such as the following:
>>    #include <stdio.h>
>>    {
>>        extern int getchar();
>>        auto int c;
>>        c=getchar();
>>At the moment, this will blow up on (all?) existing C compilers since
>>"getchar" is a macro.  Of course everyone KNOWS this and so never puts
>>such things into their code.  But under ANSI, almost any function can
>>be defined as a macro in the header files.  That means that almost
>>any program that contains an "extern type libCfunc();" in it can
>>potentially break under a conforming ANSI compiler.
>How can I know, when trying to write portable code, if the 'library'
>function I am going to use is a real function or a macro ?

Easy, you say (using the above example):

#ifndef getchar
extern int getchar();
#endif

Mark Biggar
{allegra,burdvax,cbosgd,hplabs,ihnp4,akgua,sdcsvax}!sdcrdcf!markb

brett@wjvax.UUCP (12/09/86)

In article <775@axis.UUCP> philip@axis.UUCP (Philip Peake) writes:
>In article <3800@watmath.UUCP> rbutterworth@watmath.UUCP writes:
>>
>>I can think of a perfectly conforming ANSI compiler that will break
>>almost any existing C code.  Imagine a piece of code such as the following:
>>    #include <stdio.h>
>>    {
>>        extern int getchar();
>>        auto int c;
>>        c=getchar();
>>At the moment, this will blow up on (all?) existing C compilers since
>>"getchar" is a macro.  Of course everyone KNOWS this and so never puts
>>such things into their code.  But under ANSI, almost any function can
>>be defined as a macro in the header files.  That means that almost
>>any program that contains an "extern type libCfunc();" in it can
>>potentially break under a conforming ANSI compiler.
>>
>>This change may or may not be a good thing; I don't know.
>>I do know that my own coding style has changed drastically
>>because of it.  I used to put explicit extern statements for
>>all the functions I use, simply to document the fact that I
>>am using them.  Now I NEVER put extern statements into ANY
>>source.c file.
>
>This is a *very* good point ! (Why didn't I think of it ? ......)
>
>My personal coding style has changed considerably over the years, and
>one of the directions in which it evolved was to ALWAYS put extern
>declarations of any functions that I use. 
>
>I started by putting them into a header file, this gets to be a pain,
>since we either have a header file for each C file, or lots of redundant
>extern declarations, and 'make' going beserk if you change one of the
>declarations.
>
>I now put them into the C file - I think its cleaner, and I like to be able
>to find the type of a function when I am looking at a piece of code.
>
>Taking the above example (sligthly modified), what if the function
>actually returns something other than int ?
>
>You HAVE to put the extern definition, if not other things will
>probably (certainly ?) break.
>
>How can I know, when trying to write portable code, if the 'library'
>function I am going to use is a real function or a macro ?
>

Since the only case this appears is in library functions, many of which
have header files anyhow (e.g. stdio), what is the cost of letting the
header file for a package do the extern references for the functions
available in that package (in BSD4.2, egs. curses.h, strings.h)?  This
does have the virtue of solving the problem, as was noted by the first
poster.

My real question is in implementation -- are there any loaders/compilers which
(stupidly) link in text which is referenced in an extern but not used?  If so,
this method can lead to grossly wasteful binaries when you want to use only
a few of the functions available in a package, but the header kindly
declares all of them extern.  I ask first to know if I am
likely to be bitten by this with code that I have already written, and second
possibly to influence any current standardization efforts to ban such behaviour
by a loader/compiler.
-- 
-------------
Brett Galloway
{pesnta,twg,ios,qubix,turtlevax,tymix,vecpyr,certes,isi}!wjvax!brett

gwyn@brl-smoke.ARPA (Doug Gwyn ) (12/15/86)

In article <775@axis.UUCP> philip@axis.UUCP (Philip Peake) writes:
>How can I know, when trying to write portable code, if the 'library'
>function I am going to use is a real function or a macro ?

The only time it can matter is if it's a macro and you need a function.
In this case, #undef it first (this is harmless if it's not a macro).

gwyn@brl-smoke.ARPA (Doug Gwyn ) (12/15/86)

In article <780@wjvax.wjvax.UUCP> brett@wjvax.UUCP (Brett Galloway) writes:
>My real question is in implementation -- are there any loaders/compilers which
>(stupidly) link in text which is referenced in an extern but not used?

Yes, there are, but a simple trick in the compiler can avoid generating
references to unused external names.

philip@axis.UUCP (Philip Peake) (12/18/86)

In article <5446@brl-smoke.ARPA> gwyn@brl.arpa (Doug Gwyn (VLD/VMB) <gwyn>) writes:
>In article <775@axis.UUCP> philip@axis.UUCP (Philip Peake) writes:
>>How can I know, when trying to write portable code, if the 'library'
>>function I am going to use is a real function or a macro ?
>
>The only time it can matter is if it's a macro and you need a function.
>In this case, #undef it first (this is harmless if it's not a macro).

Firstly, let me make it clear that I am not specifically picking on the
author of this article - it is just a convenient example.

After my original posting I received several emails and there were several
follow-up articles. The emails were (for the most part) geuine attempts
to be helpfull (thank you people), the follow-up articles have ALL
followed the pattern above - a small extract is quoted out of context.
This may be because of a desire not to re-transmit vast chunks of previous
articles - I don't know. But in many cases the quote is selected in such
a way as to justify the comments which the person wants to make, and
is not given the same interpretation as it would have been when seen
in its original context.

I have seen this happen many times before, to many different people -
I just thought that I would comment on it.

NOW - on to the reall issue .....

Allowing implementors to choose to implement 'standard' library functions
as macros is going to just make my life more difficult. I thought that
one of the purposes of any standardisation exersise was to make peoples
lives easier (scratch one illusion ...).

Most of the follow-up articles suggest that I can use pre-processor
macro tests and undefs etc.

Any code that I have to port to many machines already has too many
#ifdef lines for my liking. They obscure the program, and in some peverse
cases you find more pre-processor code than C code !

I dont want to have to write:

#ifndef	malloc
extern char	*malloc();
#endif
#ifdef	lseek
extern	long	lseek();
#endif

and contine to do the same for every libary 'function' I want to use.
Its a horrible idea!

Another suggestion is that one relies upon the definitions in the appropriate
include files - my VAX doesn't have them, nor does my XENIX system, nor
does my PDP11 etc ...

I still have to write code to work on any of them. An XJ311 conforming
compiler is just going to be another pain in the neck - for a long time to
come. I can't tell all our clients that they have got to go out and buy
an XJ311 compiler if they want our products.

Many of the obtuse inclusions in this standard are there simply for the
convenience of certain manufacturers. Not for the convenience of those
who have to use C compilers. It allows almost ANYTHING to be called
a conforming compiler - good for buisness for the manufacturers .. they
can tell the government departments that they have a conforming compiler -
which is probably the same one that that departments programmers refused
to accept 2 years ago !

There are ways around the problem of macro-functions, but non are nice.
Why not let the compier implementors do what they should always do
anyway - work just a little bit harder, so that 10,000,000 programmers
can work just a little bit easier in the future ?

Philip

greg@utcsri.UUCP (Gregory Smith) (12/19/86)

In article <5449@brl-smoke.ARPA> gwyn@brl.arpa (Doug Gwyn (VLD/VMB) <gwyn>) writes:
>In article <780@wjvax.wjvax.UUCP> brett@wjvax.UUCP (Brett Galloway) writes:
>>My real question is in implementation -- are there any loaders/compilers which
>>(stupidly) link in text which is referenced in an extern but not used?
>
>Yes, there are, but a simple trick in the compiler can avoid generating
>references to unused external names.

Scratch the 'stupidly'. This is widely used as a mechanism to force loading
of startup code ( E.g. the code that calls 'main' ). Besides, the
decision of whether or not to load stuff must often be made before
references are resolved. As Doug says, this is better done in the
compiler ( I wouldn't call it a 'trick'...).

I guess the compiler/loader combination would be 'stupid' if unused
externs caused loading.

-- 
----------------------------------------------------------------------
Greg Smith     University of Toronto      UUCP: ..utzoo!utcsri!greg
Have vAX, will hack...

henry@utzoo.UUCP (Henry Spencer) (12/21/86)

> Many of the obtuse inclusions in this standard are there simply for the
> convenience of certain manufacturers. Not for the convenience of those
> who have to use C compilers. It allows almost ANYTHING to be called
> a conforming compiler - good for buisness for the manufacturers ...

While I sympathize with this point of view in general, it should also be
pointed out that this standard isn't going to go anywhere or be of general
use unless the manufacturers are happy with it, or at least willing to put
up with it.  A certain amount of compromise is necessary, given that manu-
facturer compliance with the standard is generally voluntary.  In particular,
the last thing we want is for somebody big -- notably AT&T or IBM -- to be
sufficiently dissatisfied that they publish their own, different, standard.
Consider the /usr/group standard and the SVID:  /usr/group was first, but
when there's a conflict, people generally go along with the latest version
of the SVID.
-- 
				Henry Spencer @ U of Toronto Zoology
				{allegra,ihnp4,decvax,pyramid}!utzoo!henry

gwyn@brl-smoke.ARPA (Doug Gwyn ) (01/05/87)

>> ... It allows almost ANYTHING to be called a conforming compiler ...

Henry Spencer provided a good response to this.  Another point,
though, is that the proposed standard is not as permissive as
has been presented.  Indeed, I know of no existing commercial
C compiler that qualifies as a "conforming ... implementation"
in the X3J11 sense.  All C vendors will have to change their
products, which is another reason why one wants to listen to
the vendors' ideas about what the standard should consist of.