[comp.lang.c] __STDC__ defined as zero a problem

mcdonald@uxe.cso.uiuc.edu (06/24/89)

I have noticed several programs posted to the net, or available
by ftp somewhere that contain lines like

#if __STDC__
  /* usually function prototypes */
#else
  /* old style declarations */
#endif

I find this a bit objectionable, in that this prevents getting the
benefits of new-style declarations using compilers that support them
but, correctly, declare __STDC__ to be zero or don't declare it at all.

It would be nice if they looked something like

#ifdef ANSI_prototypes
#undef ANSI_prototypes
#define ANSI_prototypes 1
#else
#define ANSI_prototypes 0
#endif

#if ((__STDC__) | (ANSI_prototypes))
  /* the rest as above....

Where ANSI_prototypes could be defined on the command line.

I admit that sort of stuff could lead to command-line pollution
by things like defining ANSI_trigraphs, ANSI_this, ANSI_that, etc.

On the other hand, though __STDC__ is supposed to be defined as 1 
for comforming compilers , and not redefinable, (is this correct,
standards gurus?) it might be possible in a not-really ANSI-C
compiler to make __STDC__ be defined as 0, and redefinable. The
standard surely shouldn't object to this, should it?

Your comments and flames are welcome.

Doug McDonald (mcdonald@uxe.cso.uiuc.edu)
 

gwyn@smoke.BRL.MIL (Doug Gwyn) (06/25/89)

In article <225800190@uxe.cso.uiuc.edu> mcdonald@uxe.cso.uiuc.edu writes:
>On the other hand, though __STDC__ is supposed to be defined as 1 
>for comforming compilers , and not redefinable, (is this correct,
>standards gurus?) it might be possible in a not-really ANSI-C
>compiler to make __STDC__ be defined as 0, and redefinable. The
>standard surely shouldn't object to this, should it?

This topic has previously been discussed to death.  Here is a summary:

There are already non standard-conforming implementations that predefine
__STDC__ to almost anything you could imagine, including 0, 1, and 2.

The Standard requires that a conforming implementation predefine it to
be precisely 1 (for this version of the Standard).  Small integral
values greater than 1 are intended to be defined by future revisions
of the Standard.  Application redefinition or #undef of __STDC__ is
prohibited.  The purpose of __STDC__ is to allow application source
code testing for compilation in a Standard C environment, so that the
code can exploit post-K&R standard features in such an environment.
In a non-standard environment, there are no guarantees about the
environment, although as a practical matter many applications (for
example, UNIX=based ones) will be able to make reasonable assumptions
about the available environment.

The Standard does not, because it cannot, constrain non-conforming
implementations.  However, when __STDC__ was invented by X3J11 it was
clearly intended to be the "property" of Standard C, with the hope
that C compiler vendors would cooperate with its intended purpose.
Some vendors, including AT&T and Microsoft, appear to believe that
setting __STDC__ to 0 when their nominally standard-conforming
compiler is operated with Standard-violating options enabled is a
legitimate thing to do.  I think it is clear that vendors who set
__STDC__ to 1 in such circumstances are in the wrong, and those who
set __STDC__ to 2 or some other such small positive value are just as
wrong (since they cannot possibly predict what extensions will be
supported by a future revision of the Standard).

My recommendation is for standard-conforming implementations to preset
__STDC__ to 1 (as the Standard requires) and for ALL others to leave
__STDC__ undefined.  Less acceptable but still better than other
alternatives is for non-conforming but "mostly ANSI" implementations
to preset __STDC__ to 0, even though there is no standard meaning for
such a value, which implies that portable applications cannot rely on
it.  In no case should applications be allowed to change the value of
a preset __STDC__.

Portable applications are entitled to assume that everything specified
in the Standard is available if they find __STDC__ predefined.  Really
they should not have to resort to further tests, but given the fact
that vendors have been taking liberties with __STDC__, it would be
wise to also test for __STDC__ > 0 before assuming that EXACTLY those
things specified in the Standard are available.

If your compiler vendor predefines __STDC__ in a non standard-conforming
implementation, I urge you to complain loudly to the vendor.

bright@Data-IO.COM (Walter Bright) (06/27/89)

In article <225800190@uxe.cso.uiuc.edu> mcdonald@uxe.cso.uiuc.edu writes:
>I have noticed several programs posted to the net, or available
>by ftp somewhere that contain lines like
>#if __STDC__
>  /* usually function prototypes */
>#else
>  /* old style declarations */
>#endif
>I find this a bit objectionable, in that this prevents getting the
>benefits of new-style declarations using compilers that support them
>but, correctly, declare __STDC__ to be zero or don't declare it at all.

I agree. There's also the following problem. I suspect that most real-
world compilers are going to have two compilation modes: ANSI C and
Useful C :-). In the ANSI C mode, __STDC__ will be defined, otherwise not.
The ANSI C mode will be used for/by:
	1. people writing compiler reviews for magazines
	2. validating a C compiler against an ANSI C test suite
	3. people who's boss tells them they must
Useful C will be used for/by:
	1. people writing real applications who know what they're doing
The reasons are:
	1. Trigraph support significantly slows down the scanner, which is
	   the most time-consuming part of a compiler. Trigraphs are useless,
	   and so are left out of the Useful C mode.
	2. Compilers for many machines/OSs need extensions in order to
	   efficiently support them. Examples for the PC include near/far/
	   pascal etc.
	3. The ANSI C library is a subset of the library real programmers
	   expect to find declared in the usual .h files. In ANSI C mode,
	   these declarations will be #if'd out.
In other words, ANSI C is a specification for a common subset, but
customers demand more than that for their real work.

So it's ill-advised to expect __STDC__ == PROTOTYPES_SUPPORTED. What I
use is a header file called host.h, which figures out which compiler is
in use and defines PROTOTYPES_SUPPORTED appropriately for that compiler.
For instance, a section of host.h might look like:

	#if __ZTC__ || __TURBOC__	/* if Zortech C or Turbo C	*/
	#define PROTOTYPES_SUPPORTED 1
	#endif

	#ifndef PROTOTYPES_SUPPORTED
	#define PROTOTYPES_SUPPORTED 0
	#endif

Into host.h are collected defines for all the various idiosyncrasies that
cause me trouble.

P.S. I wrote Zortech C/C++.

henry@utzoo.uucp (Henry Spencer) (06/27/89)

In article <2029@dataio.Data-IO.COM> bright@dataio.Data-IO.COM (Walter Bright) writes:
>	1. Trigraph support significantly slows down the scanner, which is
>	   the most time-consuming part of a compiler. Trigraphs are useless,
>	   and so are left out of the Useful C mode.

It's not necessary for trigraphs to be in the scanner at all, provided the
implementation supports them *somehow* (a sed script is what I'd use) for
official conformance.

>	2. Compilers for many machines/OSs need extensions in order to
>	   efficiently support them...

Let's be honest here.  Compilers for *one* particular machine and *one*
particular OS need extensions because of the awful brain-damaged Intel
processor.  It is actually possible to include such extensions without
breaking conformance even slightly, if you are careful about naming.

>	3. The ANSI C library is a subset of the library real programmers
>	   expect to find declared in the usual .h files. In ANSI C mode,
>	   these declarations will be #if'd out.

Admittedly an issue, and the best case I've yet seen for __STDC__ == 0.
-- 
NASA is to spaceflight as the  |     Henry Spencer at U of Toronto Zoology
US government is to freedom.   | uunet!attcan!utzoo!henry henry@zoo.toronto.edu

ado@elsie.UUCP (Arthur David Olson) (06/28/89)

In article <2029@dataio.Data-IO.COM>, bright@Data-IO.COM (Walter Bright) writes:
> Trigraph support significantly slows down the scanner. . .

If anyone has done measurements that support or refute this statement,
I'd appreciate hearing from you by electronic mail.
-- 
	The RCMP is to spaceflight as the Canadian government is to freedom.
	Arthur David Olson    ado@alw.nih.gov    ADO is a trademark of Ampex.

tris@alzabo.UUCP (Tris Orendorff) (06/30/89)

Hi,

     I believe that people actually want to say:
#ifdef __STDC__
and not
#if __STDC__

ado@elsie.UUCP (Arthur David Olson) (07/11/89)

In article <942@alzabo.UUCP>, tris@alzabo.UUCP (Tris Orendorff) writes:
>      I believe that people actually want to say:
> #ifdef __STDC__
> and not
> #if __STDC__

What people want to say is
	#if __STDC__ - 0
which will work if __STDC__ is undefined.
It will also work on outre systems where __STDC__ is defined to be 0.
-- 
	Arthur David Olson    ado@alw.nih.gov    ADO is a trademark of Ampex.