[comp.std.c] POSIX, ANSI C, and __STDC__

dfp@sfmin.UUCP (D.F.Prosser) (01/21/89)

Until now I've been able to keep from adding my own pronouncements
to netnews, but the continuing discussion about __STDC__ and various
related issues, and in particular, statements (both accurate and
inaccurate) about AT&T's future C compilation system have convinced
me that I, too, need to speak my piece.

Doug Gwyn (in <9422@smoke.BRL.MIL>) characterizes four compilation
system variations:
  1. cc  - behaves just like the last UNIX C compiler (UNIX, of course,
	   is a registered trademark of AT&T).
  2. acc - ANSI C conforming (allowing valid extensions).
  3. pcc - both POSIX and ANSI C conforming (in which an application
	   must have _POSIX_SOURCE #defined in order to get any
	   additional identifiers).
  4. fcc - POSIX conforming and ANSI C nonconforming only due to name
	   space additions disallowed by ANSI C.

AT&T's ANSI C-based compilation system has three versions, all
available through the cc command's new -X compilation mode option:
  cc -Xt ("transition", the default mode)
	All compatible ANSI C changes are available.  This includes
	function prototypes, void*, and the new keywords.  It is the
	intent of this mode that all code that used to compile (without
	warnings) will compile (possibly with warnings) except for
	clashes with the new keywords: const, signed, volatile.

	In those few places where ANSI C requires different semantics
	(what the ANSI C Rationale calls QUIET CHANGES), a warning will
	be issued, but the old semantics will be used.  The big example
	is value- vs. unsigned-preserving promotion rules.  All of these
	warnings are easily eliminated by writing "unambiguous code".

  cc -Xa ("ansi", eventual default mode)
	Same as -Xt except that ANSI C semantics will be used in the
	QUIET CHANGE situations.

  cc -Xc ("conforming", not intended ever to be the default mode)
	Same as -Xa except the name space is reduced to ANSI C conformance
	and all still missing, ANSI C required diagnostics are enabled.
	In order to gain access to POSIX's extra declarations, the
	_POSIX_SOURCE macro must be #defined by the application code.

(These modes can be modified by use the -v option which enables the extra
diagnostics required by ANSI C, as well as some lint-like warnings all
of which can be silenced through use of "reasonable" code--not through
use of lint comments or #pragmas.  I believe that a compiler's job is to
do its best to translate the code you gave it; it's lint's job to check
for portability problems, and so on.)

Since both AT&T and our customers want to know whether the new ANSI C
features are available during compilation, there needed to be some always
available macro name to check.  Moreover, the ANSI C standard headers need
to know whether to include names beyond those allowed by ANSI C.  However,
there was no need to distinguish between the first two modes.  We could
have made up some macro like __ANSI__ or the like, but any use of such
a name would render the application nonportable (its behavior would be
undefined with other compilation systems).  We could have made up a name
like ANSI_C that would be #defined only in -Xt and -Xa and #undef'd in
-Xc, but then the #if[def] checks would get even more complicated.  Thus,
the (obvious) solution was to always pre-#define __STDC__, but have its
value be 0 for -Xt and -Xa.  It would be 1 only when conforming: -Xc.

I still believe in this argument.  It serves both our customers and AT&T
best, it doesn't "lie" about conformance, and it follows the spirit of
the Standard.

However, Doug believes--I am guessing here as I have yet to receive the
email to which he alluded regarding this point--that application code
cannot make use of __STDC__ == 0 in any(?) way.  I note that Doug then
said (in article <9445@smoke.BRL.MIL>) that a "gentleman's agreement"
about what __STDC__ == 0 means would allow such use.  I completely agree.
This is, in fact, what I hope AT&T's __STDC__ == 0 feature will serve as
a basis for.

I would propose that __STDC__ be #defined to be 0 in C compilation systems
that meet all ANSI C conformance requires except for:
  1. the inclusion of nonconforming "common extensions" listed in A.6.5,
  2. not issuing otherwise required diagnostics when language extensions
     are used, and/or
  3. extra names declared or defined in standard headers.
If __STDC__ is 1, the compilation system must be conforming.

This seems to me to characterize the C compilation systems vendors will
have to provide to satisfy existing customers.  I don't care whether this
is the default version, or whether such a version is even available.  If
there weren't existing implementations or other standards that have
"fiddled" with the name space in the standard headers, I'd be pushing for
only conforming ANSI C use of __STDC__, but it is simply not practical.

It is worth noting that many C compilation systems will probably have
__STDC__ #defined to be 1 and will actually be nonconforming.  I would
like to believe that the nonconforming behavior is an oversight or a bug
and that the vendor will endeavor to correct the situation.  An agreement
such as the above will allow give vendors breathing room between the
strict letter of the ANSI C law, and their customers' needs.

Doug proposes (in article <9436@smoke.BRL.MIL>) that by default the UNIX
cc command should provide a pre-#defined _POSIX_SOURCE and also have
__STDC__ #defined to 1.  This would be "a lie" as I understand the ANSI C
standard (and most people figure I know it pretty well :-) since a strictly
ANSI C conforming program could end up with extra names.  His alternative
of needing a -D_POSIX_SOURCE to the cc command invocation *exactly* matches
AT&T's by invoking ``cc -Xc -D_POSIX_SOURCE''.  (Although I'd probably
recommend setting CC to this instead of CFLAGS.)


Speaking as an X3J11 member, I too (just like Doug) was disappointed with
POSIX's mutation of the proposed macro to solve the name space issue.  It
was informally agreed (over the phone) that POSIX would describe some macro
whose definition would allow an implementation to add POSIX's extra names
to the ANSI C and POSIX shared header files.  The macro could even be one
that was #defined by the system in a non-ANSI C header file, such as
<unistd.h>, so merely #including such before any shared header file would
have sufficed.  It was unfortunate that POSIX produced the inverted
version of this idea.


As a related issue, the cc command's -D and -U options do not render a
compilation system nonconforming.  They are taken to be the equivalent
series of #defines followed by a series of #undefs inserted just before
the first line of the named source file(s).  They are explicitly provided
by the application writer, and as such are not actually predefined macros.

On another point, it was stated that __STDC__ cannot be undefined or
its value be changed.  This is not true.  The behavior of a program that
attempts such operations is undefined.  (See section 3.8.8.)  No diagnostic
is required nor is an implementation constrained to ignore the request.

Finally, I believe that X3J11's decision not to describe "levels" of
conformance was appropriate and the best choice--other language standards
with such have all had problems in this regard.

Dave Prosser, AT&T X3J11 Principal, X3J11 Redactor
AT&T Bell Labs, SF1-348, (201)522-6227, dfp@attunix.att.com

mike@arizona.edu (Mike Coffin) (01/22/89)

From article <915@sfmin.UUCP>, by dfp@sfmin.UUCP (D.F.Prosser):
> I would propose that __STDC__ be #defined to be 0 in C compilation systems
> that meet all ANSI C conformance requires except for:
>   1. the inclusion of nonconforming "common extensions" listed in A.6.5,
>   2. not issuing otherwise required diagnostics when language extensions
>      are used, and/or
>   3. extra names declared or defined in standard headers.
> If __STDC__ is 1, the compilation system must be conforming.

This sounds to me like a very good system.  Is there any chance that a
note to this effect could appear in pANS (as a footnote) or in the
rationale?  I realize that pANS can not dictate the actions of
nonconforming compilers, but I think that if the above appeared ---
even as a footnote --- most compilers would honor it.

The last sentence is important.  Cheating "just a little" when
__STDC__= 1 seems like the first step toward big trouble.
-- 
Mike Coffin				mike@arizona.edu
Univ. of Ariz. Dept. of Comp. Sci.	{allegra,cmcl2}!arizona!mike
Tucson, AZ  85721			(602)621-2858

gwyn@smoke.BRL.MIL (Doug Gwyn ) (01/22/89)

In article <915@sfmin.UUCP> dfp@attunix.att.com (Dave Prosser) writes:
>On another point, it was stated that __STDC__ cannot be undefined or
>its value be changed.

A strictly conforming program cannot #undef either __STDC__ or
_POSIX_SOURCE.  (I think someone suggested #undefing the latter
to obtain a strictly conforming C environment within a POSIX
implementation.)

Thanks very much for the comments.  They clear up some confusion about
what is going on.  If you want vendors to "follow AT&T's lead" in the
use of __STDC__==0, AT&T had better work with them NOW, because it's
already starting to happen in what appears to be an uncoordinated way.

gwyn@smoke.BRL.MIL (Doug Gwyn ) (01/22/89)

In article <8825@megaron.arizona.edu> mike@arizona.edu (Mike Coffin) writes:
-From article <915@sfmin.UUCP>, by dfp@sfmin.UUCP (D.F.Prosser):
-> I would propose that __STDC__ be #defined to be 0 in C compilation systems
-> that meet all ANSI C conformance requires except for:
...
-> If __STDC__ is 1, the compilation system must be conforming.
-This sounds to me like a very good system.  Is there any chance that a
-note to this effect could appear in pANS (as a footnote) or in the
-rationale?  I realize that pANS can not dictate the actions of
-nonconforming compilers, but I think that if the above appeared ---
-even as a footnote --- most compilers would honor it.

As the main "noisemaker" about this issue, I'll back such a solution
if it appears that we can get a solid majority of the compiler vendors
to adhere to it (and to NOT #define __STDC__ at all in any other case).

Basically, as an application developer I just need to know what __STDC__
means, so I can determine how to use it to my advantage.  I feel sure
it HAS a use, if the vendors don't ruin it..

walter@hpclwjm.HP.COM (Walter Murray) (01/24/89)

Excerpts from D.F.Prosser's note:

>   cc -Xt ("transition", the default mode)
>	In those few places where ANSI C requires different semantics
>	(what the ANSI C Rationale calls QUIET CHANGES), a warning will
>	be issued, but the old semantics will be used.  The big example
>	is value- vs. unsigned-preserving promotion rules.  

>Thus, the (obvious) solution was to always pre-#define __STDC__, but
>have its value be 0 for -Xt and -Xa.

>I would propose that __STDC__ be #defined to be 0 in C compilation systems
>that meet all ANSI C conformance requires except for:
>  1. the inclusion of nonconforming "common extensions" listed in A.6.5,
>  2. not issuing otherwise required diagnostics when language extensions
>     are used, and/or
>  3. extra names declared or defined in standard headers.
 
Am I missing something, or is there a contradiction here?  Your
"transition" mode seems to violate your proposal, in that it defines
__STDC__ to be 0, yet follows unsigned-preserving promotion rules.

Walter Murray
----------