Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

"5.1.2.2.1 Program startup" change rationale

45 views
Skip to first unread message

Larry Weiss

unread,
Sep 21, 2000, 3:00:00 AM9/21/00
to
Regarding C99's 5.1.2.2.1 (listed below), that last sentence clause
"or in some other implementation-defined manner" was not present
in C89. Why was it added in C99 ?

5.1.2.2.1 Program startup
The function called at program startup is named main.
The implementation declares no prototype for this function.
It shall be defined with a return type of int and with no
parameters:
int main(void) { /* ... */ }
or with two parameters (referred to here as argc and argv,
though any names may be used, as they are local to the
function in which they are declared):
int main(int argc, char *argv[]) { /* ... */ }
or equivalent; or in some other implementation-defined
manner.

- Larry Weiss

Barry Margolin

unread,
Sep 21, 2000, 3:00:00 AM9/21/00
to
In article <2CAD5C110AEA43D1.00EBF311...@lp.airnews.net>,

Larry Weiss <l...@airmail.net> wrote:
>Regarding C99's 5.1.2.2.1 (listed below), that last sentence clause
>"or in some other implementation-defined manner" was not present
>in C89. Why was it added in C99 ?

Probably to allow for systems like Unix, which supports a third argument,
envp.

> 5.1.2.2.1 Program startup
> The function called at program startup is named main.
> The implementation declares no prototype for this function.
> It shall be defined with a return type of int and with no
> parameters:
> int main(void) { /* ... */ }
> or with two parameters (referred to here as argc and argv,
> though any names may be used, as they are local to the
> function in which they are declared):
> int main(int argc, char *argv[]) { /* ... */ }
> or equivalent; or in some other implementation-defined
> manner.

--
Barry Margolin, bar...@genuity.net
Genuity, Burlington, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.

dke...@best.com

unread,
Sep 21, 2000, 3:00:00 AM9/21/00
to
In article <7Nty5.25$NM4.1233@burlma1-snr2>,

Barry Margolin <bar...@genuity.net> wrote:
>In article <2CAD5C110AEA43D1.00EBF311...@lp.airnews.net>,
>Larry Weiss <l...@airmail.net> wrote:
>>Regarding C99's 5.1.2.2.1 (listed below), that last sentence clause
>>"or in some other implementation-defined manner" was not present
>>in C89. Why was it added in C99 ?
>
>Probably to allow for systems like Unix, which supports a third argument,
>envp.

Sure, but Unix also supported that well before 1989. What
changed to make the standard-writers bless this invocation
between last time and this time?


--
Dave Eisen Sequoia Peripherals: (650) 967-5644
dke...@well.com FAX: (650) 967-5648
There's something in my library to offend everybody.
--- Washington Coalition Against Censorship

Barry Margolin

unread,
Sep 21, 2000, 3:00:00 AM9/21/00
to
In article <8qdugf$2ce2$1...@nntp1.ba.best.com>, <dke...@best.com> wrote:
>In article <7Nty5.25$NM4.1233@burlma1-snr2>,
>Barry Margolin <bar...@genuity.net> wrote:
>>In article <2CAD5C110AEA43D1.00EBF311...@lp.airnews.net>,
>>Larry Weiss <l...@airmail.net> wrote:
>>>Regarding C99's 5.1.2.2.1 (listed below), that last sentence clause
>>>"or in some other implementation-defined manner" was not present
>>>in C89. Why was it added in C99 ?
>>
>>Probably to allow for systems like Unix, which supports a third argument,
>>envp.
>
>Sure, but Unix also supported that well before 1989. What
>changed to make the standard-writers bless this invocation
>between last time and this time?

They realized their omission, perhaps.

Of course, an implementation could always allow the extension, but it
wouldn't be standard-conforming if it doesn't issue a diagnostic. This
allows a program that uses that feature to be conforming (but not strictly
conforming), so a conforming implementation can accept it silently.

Paul Jarc

unread,
Sep 21, 2000, 3:00:00 AM9/21/00
to
Barry Margolin <bar...@genuity.net> writes:
> In article <2CAD5C110AEA43D1.00EBF311...@lp.airnews.net>,
> Larry Weiss <l...@airmail.net> wrote:
> >Regarding C99's 5.1.2.2.1 (listed below), that last sentence clause
> >"or in some other implementation-defined manner" was not present
> >in C89. Why was it added in C99 ?
>
> Probably to allow for systems like Unix, which supports a third argument,
> envp.

Those systems were already allowed to accept other forms of main().
The difference is that now they're encouraged to document the forms
they accept.


paul

Larry Weiss

unread,
Sep 21, 2000, 3:00:00 AM9/21/00
to
Barry Margolin wrote:
> In article <8qdugf$2ce2$1...@nntp1.ba.best.com>, <dke...@best.com> wrote:
> >In article <7Nty5.25$NM4.1233@burlma1-snr2>,
> >Barry Margolin <bar...@genuity.net> wrote:
> >>In article <2CAD5C110AEA43D1.00EBF311...@lp.airnews.net>,
> >>Larry Weiss <l...@airmail.net> wrote:
> >>>Regarding C99's 5.1.2.2.1 (listed below), that last sentence clause
> >>>"or in some other implementation-defined manner" was not present
> >>>in C89. Why was it added in C99 ?
> >>
> >>Probably to allow for systems like Unix, which supports a third
> >>argument, envp.
> >
> >Sure, but Unix also supported that well before 1989. What
> >changed to make the standard-writers bless this invocation
> >between last time and this time?
>
> They realized their omission, perhaps.
> Of course, an implementation could always allow the extension, but it
> wouldn't be standard-conforming if it doesn't issue a diagnostic. This
> allows a program that uses that feature to be conforming (but not
> strictly conforming), so a conforming implementation can accept it
> silently.
>

Additionally those implementations must document their definitions?

I'm starting to see the pattern. The Standard can grant deferring
certain definitions to the implementations on the promise that those
implementations document those definitions.

- Larry Weiss

Douglas A. Gwyn

unread,
Sep 21, 2000, 3:00:00 AM9/21/00
to
Larry Weiss wrote:
> I'm starting to see the pattern. The Standard can grant deferring
> certain definitions to the implementations on the promise that those
> implementations document those definitions.

As somebody else pointed out, the intent is to allow such extensions
without having to generate diagnostics when they're used. This has
no effect on a strictly conforming program, which cannot use such
extensions.

Keith Thompson

unread,
Sep 21, 2000, 3:00:00 AM9/21/00
to
Dan...@cern.ch (Dan Pop) writes:
[...]
> Programs defining main in any way which is not compatible with one of
> the two explicitly listed in the standard invoke undefined behaviour.
> Both in C89 and in C99.

Hmm. That doesn't quite match my understanding of the C99 rules.

If my C99 compiler documents a third form for main, say
int main(int argc, char **argv, char **envp);
then a program that uses that form depends on an
implementation-defined extension, but it doesn't invoke undefined
behavior *if compiled with that compiler*.

--
Keith Thompson (The_Other_Keith) k...@cts.com <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://www.sdsc.edu/~kst>
Welcome to the last year of the 20th century.

Keith Thompson

unread,
Sep 21, 2000, 3:00:00 AM9/21/00
to
Dan...@cern.ch (Dan Pop) writes:

> In <yecn1h1...@king.cts.com> Keith Thompson <k...@cts.com> writes:
>
> >Dan...@cern.ch (Dan Pop) writes:
> >[...]
> >> Programs defining main in any way which is not compatible with one of
> >> the two explicitly listed in the standard invoke undefined behaviour.
> >> Both in C89 and in C99.
> >
> >Hmm. That doesn't quite match my understanding of the C99 rules.
> >
> >If my C99 compiler documents a third form for main, say
> > int main(int argc, char **argv, char **envp);
> >then a program that uses that form depends on an
> >implementation-defined extension, but it doesn't invoke undefined
> >behavior *if compiled with that compiler*.
>
> Undefined behaviour, as defined in C99, is not determined by what
> compiler is used:
>
> [#1] undefined behavior
> behavior, upon use of a nonportable or erroneous program
> construct, of erroneous data, or of indeterminately valued
> objects, for which this International Standard imposes no
> requirements
>
> If the C99 standard imposes any requirements on, say
>
> int main(int argc, char **argv, char **envp) {/* ... */}
>
> please cite chapter and verse.

I see your point, but I suspect that wasn't the intent.

I presume there's some intended connection between the term
"implementation-defined behavior", defined in 3.4 as "unspecified
behavior where each implementation documents how the choice is made",
and the phrase "or in some other implementation-defined manner" in
5.1.2.2.1. But since one refers to behavior and the other refers to
definitions of main, it's difficult to tell what the connection is.
There are several other places where the standard uses the phrase
"implementation-defined" that are neither "implementation-defined
behavior" (3.4) nor "implementation-defined values" (3.17.1).

I suppose one could argue that, for an implementation that defines
that it accepts the extra argument, the standard places the same
requirements on
int main(int argc, char **argv, char **envp) {/* ... */}
that it places on
int foo(int argc, char **argv, char **envp) {/* ... */}
(after all, main is a function).

Another way to look at it is that, for anything
implementation-defined, the standard requires it to behave in the
manner defined by the implementation.

In any case, if an implementation says it supports
int main(int argc, char **argv, char **envp) {/* ... */}
and it makes demons fly out my nose, I *will* submit a sternly worded
bug report (unless that's the behavior defined by the implementation,
of course).

Dan Pop

unread,
Sep 21, 2000, 8:01:27 PM9/21/00
to
In <lbvy5.33$NM4.1496@burlma1-snr2> Barry Margolin <bar...@genuity.net> writes:

>In article <8qdugf$2ce2$1...@nntp1.ba.best.com>, <dke...@best.com> wrote:
>>In article <7Nty5.25$NM4.1233@burlma1-snr2>,
>>Barry Margolin <bar...@genuity.net> wrote:
>>>In article <2CAD5C110AEA43D1.00EBF311...@lp.airnews.net>,
>>>Larry Weiss <l...@airmail.net> wrote:
>>>>Regarding C99's 5.1.2.2.1 (listed below), that last sentence clause
>>>>"or in some other implementation-defined manner" was not present
>>>>in C89. Why was it added in C99 ?
>>>
>>>Probably to allow for systems like Unix, which supports a third argument,
>>>envp.
>>
>>Sure, but Unix also supported that well before 1989. What
>>changed to make the standard-writers bless this invocation
>>between last time and this time?
>
>They realized their omission, perhaps.
>
>Of course, an implementation could always allow the extension, but it
>wouldn't be standard-conforming if it doesn't issue a diagnostic. This
>allows a program that uses that feature to be conforming (but not strictly
>conforming), so a conforming implementation can accept it silently.

Programs defining main in any way which is not compatible with one of


the two explicitly listed in the standard invoke undefined behaviour.

Both in C89 and in C99. So:

1. A compiler has never been required to diagnose a non-standard compliant
definition of main.

2. A compiler could always support *any* other definitions of main and
it was never been required to document this. The C99 standard still
doesn't change this, because undefined behaviour needs not any kind
of documentation.

3. A strictly conforming program could never use an incompatible
definition of main. A conforming program could always use an
incompatible definition of main.

The "or in some other implementation-defined manner" words don't seem to
serve any purpose, as far as I can tell. What *exactly* was the point in
adding them?

Dan
--
Dan Pop
CERN, IT Division
Email: Dan...@cern.ch
Mail: CERN - IT, Bat. 31 1-014, CH-1211 Geneve 23, Switzerland

Chris Torek

unread,
Sep 21, 2000, 8:19:06 PM9/21/00
to
>>>Larry Weiss <l...@airmail.net> wrote:
>>>>Regarding C99's 5.1.2.2.1 (listed below), that last sentence clause
>>>>"or in some other implementation-defined manner" was not present
>>>>in C89. Why was it added in C99 ?

>>In article <7Nty5.25$NM4.1233@burlma1-snr2>
>>Barry Margolin <bar...@genuity.net> suggested:


>>>Probably to allow for systems like Unix, which supports a third argument,
>>>envp.

>In article <8qdugf$2ce2$1...@nntp1.ba.best.com> <dke...@best.com> noted:


>>Sure, but Unix also supported that well before 1989. What
>>changed to make the standard-writers bless this invocation
>>between last time and this time?

In article <lbvy5.33$NM4.1496@burlma1-snr2>


Barry Margolin <bar...@genuity.net> writes:
>Of course, an implementation could always allow the extension, but it
>wouldn't be standard-conforming if it doesn't issue a diagnostic.

Not true -- the requirement that main() have one of the two forms:

int main(void)

or:

int main(int, char **)

was never in a "constraints" section, so no diagnostic for "void
main" or "int main(int, char **, char **)" or any other form was
*ever* required.

The new clause has no actual effect. It really just hints to
implementors that they can do what they have already been doing
for years, and suggests to them that it might be a good idea to
document their extensions. (Perhaps most vendors historically
preferred expending many man-months of effort on extensions and
never once even *hinting* that said vendor-specific extensions
existed. :-) As we all know, vendors never try to lock customers
in via vendor-specific features, oh no....)
--
In-Real-Life: Chris Torek, Berkeley Software Design Inc
El Cerrito, CA, USA Domain: to...@bsdi.com +1 510 234 3167
http://claw.bsdi.com/torek/ (not always up) I report spam to abuse@.

Dan Pop

unread,
Sep 21, 2000, 10:26:28 PM9/21/00
to
In <39CA85DA...@null.net> "Douglas A. Gwyn" <DAG...@null.net> writes:

>Larry Weiss wrote:
>> I'm starting to see the pattern. The Standard can grant deferring
>> certain definitions to the implementations on the promise that those
>> implementations document those definitions.
>
>As somebody else pointed out, the intent is to allow such extensions
>without having to generate diagnostics when they're used.

What part of C89 *required* the generation of a diagnostic when such
extensions were used?

Dan Pop

unread,
Sep 21, 2000, 10:33:00 PM9/21/00
to
In <yecn1h1...@king.cts.com> Keith Thompson <k...@cts.com> writes:

>Dan...@cern.ch (Dan Pop) writes:
>[...]

>> Programs defining main in any way which is not compatible with one of
>> the two explicitly listed in the standard invoke undefined behaviour.
>> Both in C89 and in C99.
>

>Hmm. That doesn't quite match my understanding of the C99 rules.
>
>If my C99 compiler documents a third form for main, say
> int main(int argc, char **argv, char **envp);
>then a program that uses that form depends on an
>implementation-defined extension, but it doesn't invoke undefined
>behavior *if compiled with that compiler*.

Undefined behaviour, as defined in C99, is not determined by what
compiler is used:

[#1] undefined behavior
behavior, upon use of a nonportable or erroneous program
construct, of erroneous data, or of indeterminately valued
objects, for which this International Standard imposes no
requirements

If the C99 standard imposes any requirements on, say

int main(int argc, char **argv, char **envp) {/* ... */}

please cite chapter and verse.

Dan

Clive D.W. Feather

unread,
Sep 26, 2000, 3:00:00 AM9/26/00
to
In article <2CAD5C110AEA43D1.00EBF311...@lp.airnew
s.net>, Larry Weiss <l...@airmail.net> writes

>Regarding C99's 5.1.2.2.1 (listed below), that last sentence clause
>"or in some other implementation-defined manner" was not present
>in C89. Why was it added in C99 ?

To encourage implementers to document it and, since it is an extension,
to make it clear that it isn't part of the core language. [In other
words, to persuade people that "void main ()" isn't real C.]

A program using such a documented interface is relying on
implementation-defined, but *not* undefined, behaviour.

--
Clive D.W. Feather | Internet Expert | Work: <cl...@demon.net>
Tel: +44 20 8371 1138 | Demon Internet | Home: <cl...@davros.org>
Fax: +44 20 8371 1037 | Thus plc | Web: <http://www.davros.org>
Written on my laptop; please observe the Reply-To address

Clive D.W. Feather

unread,
Sep 26, 2000, 3:00:00 AM9/26/00
to
In article <8qdugf$2ce2$1...@nntp1.ba.best.com>, dke...@best.com writes

>Sure, but Unix also supported that well before 1989. What
>changed to make the standard-writers bless this invocation
>between last time and this time?

Me :-)

[Seriously, it was something that I proposed, though I don't now
remember what led me to do so.]

Clive D.W. Feather

unread,
Sep 26, 2000, 3:00:00 AM9/26/00
to
In article <8qegcs$rj5$1...@sunnews.cern.ch>, Dan Pop <Dan...@cern.ch>
writes

>If the C99 standard imposes any requirements on, say
>
> int main(int argc, char **argv, char **envp) {/* ... */}
>
>please cite chapter and verse.

5.1.2.2.3 Program termination

[#1] If the return type of the main function is a type
compatible with int, a return from the initial call to the
main function is equivalent to calling the exit function
with the value returned by the main function as its
argument;10) reaching the } that terminates the main
function returns a value of 0. If the return type is not
compatible with int, the termination status returned to the
host environment is unspecified.

It's also arguable that 5.1.2.2.1's requirements on argc and argv
continue to apply.

Keith Thompson

unread,
Sep 26, 2000, 3:00:00 AM9/26/00
to
"Clive D.W. Feather" <cl...@on-the-train.demon.co.uk> writes:
> In article <8qegcs$rj5$1...@sunnews.cern.ch>, Dan Pop <Dan...@cern.ch>
> writes
> >If the C99 standard imposes any requirements on, say
> >
> > int main(int argc, char **argv, char **envp) {/* ... */}
> >
> >please cite chapter and verse.
[...]

> It's also arguable that 5.1.2.2.1's requirements on argc and argv
> continue to apply.

Arguable, but IMHO not successfully arguable. Just because an
alternative form for main happens to have an int and a char** as its
first two arguments, I see no basis for assuming that they're the
classic argc and argv.

<OT>
If I were designing C from scratch today, with no concern for backward
compatibility, I'd probably make the main program void main(void) and
provide routines in <stdlib.h> to access command-line arguments and
set the return status. Or, more likely, I'd make so many other
changes that the previous sentence wouldn't even make much sense.
Fortunately for the world, I have neither the opportunity nor the time
to do so.
</OT>

Dan Pop

unread,
Sep 26, 2000, 3:00:00 AM9/26/00
to
In <snIthWJ26M05Ew7$@romana.davros.org> "Clive D.W. Feather" <cl...@on-the-train.demon.co.uk> writes:

>In article <2CAD5C110AEA43D1.00EBF311...@lp.airnew
>s.net>, Larry Weiss <l...@airmail.net> writes
>>Regarding C99's 5.1.2.2.1 (listed below), that last sentence clause
>>"or in some other implementation-defined manner" was not present
>>in C89. Why was it added in C99 ?
>
>To encourage implementers to document it and, since it is an extension,
>to make it clear that it isn't part of the core language. [In other
>words, to persuade people that "void main ()" isn't real C.]
>
>A program using such a documented interface is relying on
>implementation-defined, but *not* undefined, behaviour.

So, we no longer use the text of the standard to decide whether a
program invokes undefined behaviour or not, but the documentation of the
compiler. This leads to the situation where void main() is undefined
behaviour if compiled with compiler A, but implementation defined
behaviour if compiled with compiler B, which documents this interface.

So, why does the standard bothers with the concept of undefined behaviour
at all, since any compiler can define and document any instance of
undefined behaviour it wants? What is the difference between

void main() {/* ... */}

and

int i = INT_MAX;
i++;

as far as undefined behaviour is concerned? Compiler A may define
void main and compiler B may define signed integer arithmetic overflow.

The only sane interpretation of the standard is that there is no
difference: both are undefined behaviour. A compiler is not *required*
by the standard to define void main any more than it is required to
define signed integer arithmetic overflow.

So, the effect of "or in some other implementation-defined manner" is
void and null :-)

Clint Helton

unread,
Sep 26, 2000, 3:00:00 AM9/26/00
to
"Clive D.W. Feather" wrote:
.
.
.

> words, to persuade people that "void main ()" isn't real C.]
>

This should be flagged as "'void' where prohibited" :)
--
Alcatel USA Email: che...@usa.alcatel.com
1000 Coit Road
Plano, Texas 75075-5813 *** The opinions expressed herein ***
MS CLDC *** are not those of Alcatel USA. ***

Niklas Matthies

unread,
Sep 26, 2000, 3:00:00 AM9/26/00
to
In comp.std.c, Dan Pop <Dan...@cern.ch> writes:
> In <snIthWJ26M05Ew7$@romana.davros.org> "Clive D.W. Feather" <cl...@on-the-train.demon.co.uk> writes:
>
>>In article <2CAD5C110AEA43D1.00EBF311...@lp.airnew
>>s.net>, Larry Weiss <l...@airmail.net> writes
>>>Regarding C99's 5.1.2.2.1 (listed below), that last sentence clause
>>>"or in some other implementation-defined manner" was not present
>>>in C89. Why was it added in C99 ?
>>
>>To encourage implementers to document it and, since it is an extension,
>>to make it clear that it isn't part of the core language. [In other
>>words, to persuade people that "void main ()" isn't real C.]
>>
>>A program using such a documented interface is relying on
>>implementation-defined, but *not* undefined, behaviour.
>
> So, we no longer use the text of the standard to decide whether a
> program invokes undefined behaviour or not, but the documentation of the
> compiler.

You seem to misunderstand the notion of "undefined behaviour". It
doesn't mean some sort of actual behaviour, it just means that the
standard does not define any behaviour at all. It is almost equivalent
to say that a program (run) where an instance of "undefined behaviour"
occurs, semantically is not a C program at all, and a compiler may
assume that it will never get such a program as input, and still be
completely conforming.

In contrast, "implementation-defined" means that this is still a C
program, but the implementation gets to choose the actual behaviour
(usually from a specific set defined by the standard), and must
document its choice.

> This leads to the situation where void main() is undefined
> behaviour if compiled with compiler A, but implementation defined
> behaviour if compiled with compiler B, which documents this interface.

No. It is always implementation-defined. The point is, *if* a compiler
allows other forms of main() (i.e. doesn't issue a diagnostic for it),
then it must document the behaviour of those other forms. If it fails
to do so, then the compiler is not conforming.

> So, why does the standard bothers with the concept of undefined behaviour
> at all, since any compiler can define and document any instance of
> undefined behaviour it wants?

It can't. Whatever it documents, if it is related to something that
the standard specifies as being implementation-defined, then it can't
be "undefined behaviour" in the sense of the standard.

> What is the difference between
>
> void main() {/* ... */}
>

If the compiler supports this form, then it must document what
behaviour it has. If it doesn't support this form, it must issue a
diagnostic.

> int i = INT_MAX;
> i++;

The compiler can do anything it likes. The compiler writer is allowed
to completely ignore the possibility of such code (if it is executed).

-- Niklas

Larry Weiss

unread,
Sep 26, 2000, 3:00:00 AM9/26/00
to
Dan Pop wrote:
> So, the effect of "or in some other implementation-defined manner" is
> void and null :-)
>

And it should be promptly removed from the Standard.

Especially since its champion can't recall any rationale for
adding it:

"[Seriously, it was something that I proposed, though I don't now

remember what led me to do so.]" - Clive D.W. Feather

That additional sentence clause is wrecking havoc over in c.l.c as
"evidence" that void main() is Standard C afterall, when it is no
such thing, but the waters have been muddied just enough that those
proponents of void main() are now concocting all sorts of elaboration
to justify that unwarranted assertion. People I would rather
continue to respect over there are seeing mirages of nonsense in
that simple clause. Please elide it.

- Larry Weiss

Dan Pop

unread,
Sep 26, 2000, 3:00:00 AM9/26/00
to
In <8qr0t3$sk2q$1...@hades.rz.uni-sb.de> Niklas Matthies <matt...@fsinfo.cs.uni-sb.de> writes:

>In comp.std.c, Dan Pop <Dan...@cern.ch> writes:
>> In <snIthWJ26M05Ew7$@romana.davros.org> "Clive D.W. Feather" <cl...@on-the-train.demon.co.uk> writes:
>>
>>>In article <2CAD5C110AEA43D1.00EBF311...@lp.airnew
>>>s.net>, Larry Weiss <l...@airmail.net> writes
>>>>Regarding C99's 5.1.2.2.1 (listed below), that last sentence clause
>>>>"or in some other implementation-defined manner" was not present
>>>>in C89. Why was it added in C99 ?
>>>
>>>To encourage implementers to document it and, since it is an extension,
>>>to make it clear that it isn't part of the core language. [In other
>>>words, to persuade people that "void main ()" isn't real C.]
>>>
>>>A program using such a documented interface is relying on
>>>implementation-defined, but *not* undefined, behaviour.
>>
>> So, we no longer use the text of the standard to decide whether a
>> program invokes undefined behaviour or not, but the documentation of the
>> compiler.
>
>You seem to misunderstand the notion of "undefined behaviour".

I don't misunderstand it at all. It is the previous poster who is
using it in a rather strange way.

>It
>doesn't mean some sort of actual behaviour, it just means that the
>standard does not define any behaviour at all.

As far as I can tell, void main fits the bill quite well.

>It is almost equivalent
>to say that a program (run) where an instance of "undefined behaviour"
>occurs, semantically is not a C program at all, and a compiler may
>assume that it will never get such a program as input, and still be
>completely conforming.

Yup. Is there are any requirement that void main is not handled in this
way? If not, void main is undefined behaviour.

>In contrast, "implementation-defined" means that this is still a C
>program, but the implementation gets to choose the actual behaviour
>(usually from a specific set defined by the standard), and must
>document its choice.

Does void main fit the bill here? NO, as far as I can tell.

>> This leads to the situation where void main() is undefined
>> behaviour if compiled with compiler A, but implementation defined
>> behaviour if compiled with compiler B, which documents this interface.
>
>No. It is always implementation-defined.

Now, you're the one who doesn't understand the notion of
"implementation-defined" behaviour. If is implementation-defined, then
*each and every* implementation must *support* and *document* it. And not
only void main but ALL the possible definitions of main, which are a
practical infinity!

>The point is, *if* a compiler
>allows other forms of main() (i.e. doesn't issue a diagnostic for it),
>then it must document the behaviour of those other forms. If it fails
>to do so, then the compiler is not conforming.

This statement is at odds with the definition of "implementation-defined"
behaviour in the standard. With or without diagnostic,
implementation-defined means the feature is supported and documented,
there is no place for if's here.

>> So, why does the standard bothers with the concept of undefined behaviour
>> at all, since any compiler can define and document any instance of
>> undefined behaviour it wants?
>
>It can't. Whatever it documents, if it is related to something that
>the standard specifies as being implementation-defined, then it can't
>be "undefined behaviour" in the sense of the standard.
>
>> What is the difference between
>>
>> void main() {/* ... */}
>>
>
>If the compiler supports this form, then it must document what
>behaviour it has. If it doesn't support this form, it must issue a
>diagnostic.

5.1.1.3 Diagnostics

[#1] A conforming implementation shall produce at least one
diagnostic message (identified in an implementation-defined
manner) if a preprocessing translation unit or translation
unit contains a violation of any syntax rule or constraint,
even if the behavior is also explicitly specified as
undefined or implementation-defined. Diagnostic messages
need not be produced in other circumstances.

...
5.1.2.2.1 Program startup

[#1] The function called at program startup is named main.


The implementation declares no prototype for this function.
It shall be defined with a return type of int and with no
parameters:

int main(void) { /* ... */ }

or with two parameters (referred to here as argc and argv,
though any names may be used, as they are local to the
function in which they are declared):

int main(int argc, char *argv[]) { /* ... */ }

or equivalent; or in some other implementation-defined
manner.

The text we are talking about is neither a syntax rule nor part of a
constraint. So, where did you get the idea about the necessity of a
diagnostic if void main is not supported? The standard clearly says:

Diagnostic messages need not be produced in other circumstances.

Or am I missing something?

Phil Tregoning

unread,
Sep 27, 2000, 3:00:00 AM9/27/00
to

Clive D.W. Feather <cl...@on-the-train.demon.co.uk> wrote in article
<snIthWJ26M05Ew7$@romana.davros.org>...


> In article <2CAD5C110AEA43D1.00EBF311...@lp.airnew
> s.net>, Larry Weiss <l...@airmail.net> writes
> >Regarding C99's 5.1.2.2.1 (listed below), that last sentence clause
> >"or in some other implementation-defined manner" was not present
> >in C89. Why was it added in C99 ?
>
> To encourage implementers to document it and, since it is an extension,
> to make it clear that it isn't part of the core language. [In other
> words, to persuade people that "void main ()" isn't real C.]
>

I quite like Compaq C's (aka DEC C for VMS) diagnostic
of the void main() extension when compiled with the
warnings turned way way up:

$ CC /WARNING=(ENABLE=ALL,VERBOSE)/STANDARD=ANSI89 TEST.C

void main(void) {}
^
%CC-I-MAINNOTINT, Strict standard C extension: The
declaration of the "main" function has a return type
other than int.
at line number 1 in file TEST.C;1
Description: Standard C requires that the "main"
function be defined with a return type of int. Compaq
C will accept other return types, but the program does
not conform to the C standard. The status value
returned to the environment may not be what you expect,
and other C compilers may not accept the definition as
written.
User Action: Define the "main" function with a return
type of int for maximal portability.

I kid you not!

Looks like Compaq took the encouragement to heart :)

Phil T

Douglas A. Gwyn

unread,
Sep 27, 2000, 3:00:00 AM9/27/00
to
Larry Weiss wrote:
> That additional sentence clause is wrecking havoc over in c.l.c as
> "evidence" that void main() is Standard C afterall, ...

One of the reasons I quit monitoring that newsgroup.

Of course, in comp.std.c we assume that participants
understand the difference between a strictly conforming
program, which does not exceed the minimal guarantees
for what a conforming implementation must support, and
a conforming program, which just happens to be accepted
by *some* conforming implementation. void main() is in
the latter category; some implementations will accept it
(for C99 conformance they have to document what they
guarantee they will accept), but other implementations
will not accept it.

I would say that c.l.c confusion is standard practice
for that newsgroup, and not grounds for changing the
language spec.

Ben Pfaff

unread,
Sep 27, 2000, 3:00:00 AM9/27/00
to
"Douglas A. Gwyn" <gw...@arl.army.mil> writes:

> Larry Weiss wrote:
> > That additional sentence clause is wrecking havoc over in c.l.c as
> > "evidence" that void main() is Standard C afterall, ...
>

> One of the reasons I quit monitoring that newsgroup. [...]

Hey, *some* of us in c.l.c understand the difference between
"conforming" and "strictly conforming". The problem is that the
ones who don't seem to have more time to spend on posting lately.

Clive D.W. Feather

unread,
Sep 27, 2000, 3:00:00 AM9/27/00
to
In article <8qqt86$jm4$1...@sunnews.cern.ch>, Dan Pop <Dan...@cern.ch>
writes

>>A program using such a documented interface is relying on
>>implementation-defined, but *not* undefined, behaviour.
>
>So, we no longer use the text of the standard to decide whether a
>program invokes undefined behaviour or not, but the documentation of the
>compiler. This leads to the situation where void main() is undefined

>behaviour if compiled with compiler A, but implementation defined
>behaviour if compiled with compiler B, which documents this interface.

Correct. The same as the use of a value above a lower bound is i-d on
compiler A and undefined on compiler B.

>So, why does the standard bothers with the concept of undefined behaviour
>at all, since any compiler can define and document any instance of
>undefined behaviour it wants?

"implementation-defined" does not mean "documented by the
implementation".

>A compiler is not *required*
>by the standard to define void main any more than it is required to
>define signed integer arithmetic overflow.

Correct.

>So, the effect of "or in some other implementation-defined manner" is
>void and null :-)

Wrong.

Larry Weiss

unread,
Sep 27, 2000, 3:00:00 AM9/27/00
to
"Douglas A. Gwyn" wrote:
> I would say that c.l.c confusion is standard practice
> for that newsgroup, and not grounds for changing the
> language spec.

Of course not, that sentence clause should be removed on its own
demerits alone. So far, no one can recall or reinvent any rationale
for its inclusion in the Standard. It may be benign, but then again
why include it? Is there a precedent for adding such "padding" ?

- Larry Weiss

Dan Pop

unread,
Sep 27, 2000, 3:00:00 AM9/27/00
to

>"implementation-defined" does not mean "documented by the
>implementation".

Has the following definition been dropped/changed in C99?

3.11
[#1] implementation-defined behavior


unspecified behavior where each implementation documents how
the choice is made

>>A compiler is not *required*


>>by the standard to define void main any more than it is required to
>>define signed integer arithmetic overflow.
>
>Correct.
>
>>So, the effect of "or in some other implementation-defined manner" is
>>void and null :-)
>
>Wrong.

Why?

Barry Margolin

unread,
Sep 27, 2000, 3:00:00 AM9/27/00
to
In article <8qtj86$t3t$1...@sunnews.cern.ch>, Dan Pop <Dan...@cern.ch> wrote:
>In <BoQWiwPU...@romana.davros.org> "Clive D.W. Feather"
><cl...@on-the-train.demon.co.uk> writes:
>
>>"implementation-defined" does not mean "documented by the
>>implementation".
>
>Has the following definition been dropped/changed in C99?
>
> 3.11
> [#1] implementation-defined behavior
> unspecified behavior where each implementation documents how
> the choice is made

I believe the distinction that Clive was making is that
"implementation-defined" means "required to be documented by the
implementation". If the implementation documents something, but it's not
something that the standard *requires* them to document, that documentation
is irrelevant. Although the above clause doesn't use the word "require", I
think that's understood -- the standard, after all, is a list of
requirements (either on programs or implementations).

For instance, an implementation may document that dereferencing a null
pointer always results in the SIGSEGV signal being raised. That doesn't
alter the fact that this is undefined behavior as far as the standard is
concerned.

Barry Margolin

unread,
Sep 27, 2000, 3:00:00 AM9/27/00
to
In article <0438132DA4BEF363.21CF2173...@lp.airnews.net>,

I think other, similar comments have generally been in footnotes, so
perhaps it would have been better done that way.

Niklas Matthies

unread,
Sep 27, 2000, 3:00:00 AM9/27/00
to
In comp.std.c, Clive D.W. Feather <cl...@on-the-train.demon.co.uk> writes:
> In article <8qqt86$jm4$1...@sunnews.cern.ch>, Dan Pop <Dan...@cern.ch>
> writes
[...]

>>So, the effect of "or in some other implementation-defined manner" is
>>void and null :-)
>
> Wrong.

Could you please elaborate on this?

-- Niklas

Niklas Matthies

unread,
Sep 27, 2000, 3:00:00 AM9/27/00
to
In comp.std.c, Dan Pop <Dan...@cern.ch> writes:
> In <8qr0t3$sk2q$1...@hades.rz.uni-sb.de> Niklas Matthies <matt...@fsinfo.cs.uni-sb.de> writes:
[...]

>>> This leads to the situation where void main() is undefined
>>> behaviour if compiled with compiler A, but implementation defined
>>> behaviour if compiled with compiler B, which documents this interface.
>>
>>No. It is always implementation-defined.
>
> Now, you're the one who doesn't understand the notion of
> "implementation-defined" behaviour. If is implementation-defined, then
> *each and every* implementation must *support* and *document* it. And not
> only void main but ALL the possible definitions of main, which are a
> practical infinity!

I wasn't really talking about "implementation-defined baheviour"
(which the standard has a definition for), but just about
"implementation-defined" (which the standard hasn't a definition for,
but uses the term in some places), since the wording we are talking
about is "It [main] shall be defined [...] or in some other
implementation-defined manner." Therefore, an implementation either
chooses "void main()" to be one of the "other manners" it defines, or
it does not. Hence, given a particular implementation (along with its
documentation), it is well-defined whether "void main()" is supported
or not. In particular, it is not undefined; though in the meanwhile
I agree this results in "undefined behaviour" in the way that the
standard defines it.

>>The point is, *if* a compiler
>>allows other forms of main() (i.e. doesn't issue a diagnostic for it),
>>then it must document the behaviour of those other forms. If it fails
>>to do so, then the compiler is not conforming.
>
> This statement is at odds with the definition of "implementation-defined"
> behaviour in the standard. With or without diagnostic,
> implementation-defined means the feature is supported and documented,
> there is no place for if's here.

The standard defines "implementation-defined behavior" as "unspecified
behavior where each implementation documents how the choice is made".
It doesn't specify at all what kinds of situations this can apply to,
and of course if's are allowed ("if <condition>, then the behaviour is
implementation-defined"). And, unless the standard imposes further
requirements upon a certain construct in a certain situation, the
implementation may choose to crash ("terminate abnormally") the
program in that situation, if the standard has tagged the construct in
that situation as "implementation-defined behavior", as long as it
(the implementation) documents this behaviour. I wouldn't call that
"supporting a feature".

3.8 constraint: restriction, either syntactic or semantic, by which
the exposition of language elements is to be interpreted

Certainly, the definition of the startup function is a language
element, and 5.1.2.2.1 imposes restrictions upon it. In particular, if
"void main()" is not one of the "other implementation-defined
manners" that a given implementation defines, then its use in a
program violates that restriction on that given implementation.

> Or am I missing something?

I certainly concede that I see your point, and your argument makes
sense (to me, now). But, upon further thinking while writing this
followup, I believe the standard just is not clear enough to allow a
definite answer to the question of whether the addition of "; or in
some other implementation-defined manner" has any effect.

-- Niklas


Dan Pop

unread,
Sep 27, 2000, 3:00:00 AM9/27/00
to
In <_EsA5.76$aT.1299@burlma1-snr2> Barry Margolin <bar...@genuity.net> writes:

>In article <8qtj86$t3t$1...@sunnews.cern.ch>, Dan Pop <Dan...@cern.ch> wrote:

>>In <BoQWiwPU...@romana.davros.org> "Clive D.W. Feather"


>><cl...@on-the-train.demon.co.uk> writes:
>>
>>>"implementation-defined" does not mean "documented by the
>>>implementation".
>>
>>Has the following definition been dropped/changed in C99?
>>
>> 3.11
>> [#1] implementation-defined behavior

>> unspecified behavior where each implementation documents how
>> the choice is made
>

>I believe the distinction that Clive was making is that
>"implementation-defined" means "required to be documented by the
>implementation". If the implementation documents something, but it's not
>something that the standard *requires* them to document, that documentation
>is irrelevant. Although the above clause doesn't use the word "require", I
>think that's understood -- the standard, after all, is a list of
>requirements (either on programs or implementations).

I definitely agree with this. What I don't understand is how to
interpret "or in some other implementation-defined manner" in a manner
which is consistent with the rest of the standard. Everywhere else in
the standard, "implementation-defined" means that each and every
implementation has to document its choice.

With the clause under debate, it seems that void main is either undefined
behaviour or implementation-defined behaviour. This doesn't make any
sense to me.

Barry Margolin

unread,
Sep 27, 2000, 3:00:00 AM9/27/00
to
In article <8qtt2d$4c1$1...@sunnews.cern.ch>, Dan Pop <Dan...@cern.ch> wrote:
>I definitely agree with this. What I don't understand is how to
>interpret "or in some other implementation-defined manner" in a manner
>which is consistent with the rest of the standard. Everywhere else in
>the standard, "implementation-defined" means that each and every
>implementation has to document its choice.
>
>With the clause under debate, it seems that void main is either undefined
>behaviour or implementation-defined behaviour. This doesn't make any
>sense to me.

Basically, what it's stating is that implementations must document all the
signatures of main() that they accept in addition to the standard one. But
this requirement has no teeth, because using an undocumented form invokes
undefined behavior, which the implementation can handle in any way it
wishes, including accepting it and doing something reasonable.

I guess the difference between this and most other implementation-defined
aspects of the language is that this qualifier usually refers to
*consequences* of some construct, not the acceptability of a program as in
this case.

Dan Pop

unread,
Sep 27, 2000, 3:00:00 AM9/27/00
to
In <EGsA5.77$aT.1179@burlma1-snr2> Barry Margolin <bar...@genuity.net> writes:

>In article <0438132DA4BEF363.21CF2173...@lp.airnews.net>,
>Larry Weiss <l...@airmail.net> wrote:
>>"Douglas A. Gwyn" wrote:
>>> I would say that c.l.c confusion is standard practice
>>> for that newsgroup, and not grounds for changing the
>>> language spec.
>>
>>Of course not, that sentence clause should be removed on its own
>>demerits alone. So far, no one can recall or reinvent any rationale
>>for its inclusion in the Standard. It may be benign, but then again
>>why include it? Is there a precedent for adding such "padding" ?
>
>I think other, similar comments have generally been in footnotes, so
>perhaps it would have been better done that way.

Much better, since it would have zero normative power in a footnote.
But the usage of "implementation-defined" would still remain dubious,
even in a footnote.

Dan Pop

unread,
Sep 27, 2000, 3:00:00 AM9/27/00
to
In <8qtm87$12eg8$1...@hades.rz.uni-sb.de> Niklas Matthies <matt...@fsinfo.cs.uni-sb.de> writes:

>I wasn't really talking about "implementation-defined baheviour"
>(which the standard has a definition for), but just about
>"implementation-defined" (which the standard hasn't a definition for,
>but uses the term in some places), since the wording we are talking
>about is "It [main] shall be defined [...] or in some other
>implementation-defined manner."

If plain "implementation-defined" is not supposed to have the same
meaning as "implementation-defined baheviour", then its usage in the
standard is a defect, because, not being defined, it can mean anything.

>> The text we are talking about is neither a syntax rule nor part of a
>> constraint. So, where did you get the idea about the necessity of a
>> diagnostic if void main is not supported?
>
> 3.8 constraint: restriction, either syntactic or semantic, by which
> the exposition of language elements is to be interpreted
>
>Certainly, the definition of the startup function is a language
>element, and 5.1.2.2.1 imposes restrictions upon it.

I can't see any point in playing semantic games. A "constraint" in the
standard is a paragraph *explicitly* labelled "Constraints". It is to
such paragraphs that the definition of "diagnostic" makes reference.

James Kuyper

unread,
Sep 27, 2000, 3:00:00 AM9/27/00
to
Dan Pop wrote:
>
> In <8qtm87$12eg8$1...@hades.rz.uni-sb.de> Niklas Matthies <matt...@fsinfo.cs.uni-sb.de> writes:
>
> >I wasn't really talking about "implementation-defined baheviour"
> >(which the standard has a definition for), but just about
> >"implementation-defined" (which the standard hasn't a definition for,
> >but uses the term in some places), since the wording we are talking
> >about is "It [main] shall be defined [...] or in some other
> >implementation-defined manner."
>
> If plain "implementation-defined" is not supposed to have the same
> meaning as "implementation-defined baheviour", then its usage in the
> standard is a defect, because, not being defined, it can mean anything.

The standard contains a great many phrases that are not defined in the
standard. Just try to find the standard-sanctioned definition of the
word "the". The rule is that terms which aren't defined in the standard
or in one of it's normative references are to be taken as having their
usual meaning in ordinary english.

"implementation-defined behavior" has a very specific technical meaning;
it is NOT the same as "behavior defined by the implementation". However,
"implementation-defined", when not followed by "behavior", carries it's
ordinary english meaning: "defined by the implementation" (well, almost
ordinary: "implementation" itself has a specialized meaning within the
standard).

...


> I can't see any point in playing semantic games. A "constraint" in the
> standard is a paragraph *explicitly* labelled "Constraints". It is to
> such paragraphs that the definition of "diagnostic" makes reference.

I agree with you, but I don't believe that the standard says so
explicitly.

James Kuyper

unread,
Sep 27, 2000, 3:00:00 AM9/27/00
to
Dan Pop wrote:
>
> In <BoQWiwPU...@romana.davros.org> "Clive D.W. Feather" <cl...@on-the-train.demon.co.uk> writes:
>
> >"implementation-defined" does not mean "documented by the
> >implementation".
>
> Has the following definition been dropped/changed in C99?
>
> 3.11
> [#1] implementation-defined behavior
> unspecified behavior where each implementation documents how
> the choice is made

That only defines "implementation-defined behavior", it doesn't define
"impelementation-defined". Also, notice that if an implementation
chooses to define behavior that is NOT "unspecified behavior", that
behavior does not qualify as "implementation-defined behavior", even
though it is behavior defined by the implementation.

Dan Pop

unread,
Sep 27, 2000, 3:00:00 AM9/27/00
to
In <T_uA5.86$aT.1267@burlma1-snr2> Barry Margolin <bar...@genuity.net> writes:

>In article <8qtt2d$4c1$1...@sunnews.cern.ch>, Dan Pop <Dan...@cern.ch> wrote:
>>I definitely agree with this. What I don't understand is how to
>>interpret "or in some other implementation-defined manner" in a manner
>>which is consistent with the rest of the standard. Everywhere else in
>>the standard, "implementation-defined" means that each and every
>>implementation has to document its choice.
>>
>>With the clause under debate, it seems that void main is either undefined
>>behaviour or implementation-defined behaviour. This doesn't make any
>>sense to me.
>
>Basically, what it's stating is that implementations must document all the
>signatures of main() that they accept in addition to the standard one. But
>this requirement has no teeth, because using an undocumented form invokes
>undefined behavior, which the implementation can handle in any way it
>wishes, including accepting it and doing something reasonable.

This was exactly my point when I said that this clause is void and null.
If it "has no teeth", what's the point in having it in the normative part
of the standard?

>I guess the difference between this and most other implementation-defined
>aspects of the language is that this qualifier usually refers to
>*consequences* of some construct, not the acceptability of a program as in
>this case.

The definition of "implementation-defined behaviour" in C89 explicitly
said that it refers to a "correct program construct and correct data".
Is the current definition compatible with the old one? If yes, then it
cannot apply to a program defining main as a void function, because that's
already undefined behaviour. Regardless of what the implementation
does and documents about void main.

Barry Margolin

unread,
Sep 27, 2000, 8:02:07 PM9/27/00
to
In article <8qtt66$4s0$1...@sunnews.cern.ch>, Dan Pop <Dan...@cern.ch> wrote:
>In <EGsA5.77$aT.1179@burlma1-snr2> Barry Margolin <bar...@genuity.net> writes:
>
>>In article <0438132DA4BEF363.21CF2173...@lp.airnews.net>,
>>Larry Weiss <l...@airmail.net> wrote:
>>>"Douglas A. Gwyn" wrote:
>>>> I would say that c.l.c confusion is standard practice
>>>> for that newsgroup, and not grounds for changing the
>>>> language spec.
>>>
>>>Of course not, that sentence clause should be removed on its own
>>>demerits alone. So far, no one can recall or reinvent any rationale
>>>for its inclusion in the Standard. It may be benign, but then again
>>>why include it? Is there a precedent for adding such "padding" ?
>>
>>I think other, similar comments have generally been in footnotes, so
>>perhaps it would have been better done that way.
>
>Much better, since it would have zero normative power in a footnote.
>But the usage of "implementation-defined" would still remain dubious,
>even in a footnote.

The footnote could be worded much better, e.g. "Many implementations also
support other definitions of main(), for instance to allow command-line
arguments to be ignored or to pass additional data."

Chris Torek

unread,
Sep 28, 2000, 3:00:00 AM9/28/00
to
>In <T_uA5.86$aT.1267@burlma1-snr2> Barry Margolin <bar...@genuity.net> writes:
>>Basically, what it's stating is that implementations must document all the
>>signatures of main() that they accept in addition to the standard one. But
>>this requirement has no teeth, because using an undocumented form invokes
>>undefined behavior, which the implementation can handle in any way it
>>wishes, including accepting it and doing something reasonable.

In article <8qu099$5um$1...@sunnews.cern.ch> Dan Pop <Dan...@cern.ch> wrote:
>This was exactly my point when I said that this clause is void and null.
>If it "has no teeth", what's the point in having it in the normative part
>of the standard?

Indeed.

The following is rather long, because I wrote it for comp.lang.c,
where people are not necessarily expected to understand all the
nuances. But I am not going to rewrite it for this group. :-) Hm,
okay, I will snip out some bits...

-----

The "shall" here is outside a "constraints" section, so code that
violates it -- i.e., has main defined in neither of these two ways,
nor in some other implementation-defined manner -- does not require
a diagnostic. In other words, compilers need not warn about
mis-defined and/or mis-declared "main"s. I think this point is
not in dispute; I just wanted to reiterate it.

Now, what about this "some other implementation-defined manner"?

As far as I can tell, this clause is entirely pointless. Suppose
the C standards (C89 and C99) had said instead something like:

"main ... shall be defined as returning int, and
taking either zero or two parameters ... Any other
definition results in undefined behavior."

(They do not say this, but suppose they had.) One thing any
implementation is permitted to do with undefined behavior is --
surprise! -- to define it! ...

So, if only the two forms of "main" were defined, and all other
forms were explicitly undefined, any implementation could define
new forms anyway. What, then, does the clause "or in some other
implementation-defined manner" add? ...

So this means that *if* an implementation adds implementation-defined
forms of main(), they will be documented. But -- any implementation
is free *not* to add other forms of main(), and if it were explicitly
undefined instead, any implementation that defined an undefined
form of main() *could* document it! ...

I conclude that this clause is meaningless, and might as well be
ignored. (At most, the clause is a hint: "Gee, implementors, you
might want to think about defining additional forms of main for
historical compatibility with the compilers that came with your
systems before ANSI C existed." I hardly think implementors need
such a hint.)

[and later, in what I hope was an inspired bit of satire, I added:]

The new clause has no actual effect. It really just hints to
implementors that they can do what they have already been doing
for years, and suggests to them that it might be a good idea to
document their extensions. (Perhaps most vendors historically
preferred expending many man-months of effort on extensions and
never once even *hinting* that said vendor-specific extensions
existed. :-) As we all know, vendors never try to lock customers
in via vendor-specific features, oh no....)
--
In-Real-Life: Chris Torek, Berkeley Software Design Inc
El Cerrito, CA, USA Domain: to...@bsdi.com +1 510 234 3167
http://claw.bsdi.com/torek/ (not always up) I report spam to abuse@.

Niklas Matthies

unread,
Sep 28, 2000, 3:00:00 AM9/28/00
to
In comp.std.c, Dan Pop <Dan...@cern.ch> writes:
> In <8qtm87$12eg8$1...@hades.rz.uni-sb.de> Niklas Matthies <matt...@fsinfo.cs.uni-sb.de> writes:
>
>>I wasn't really talking about "implementation-defined baheviour"
>>(which the standard has a definition for), but just about
>>"implementation-defined" (which the standard hasn't a definition for,
>>but uses the term in some places), since the wording we are talking
>>about is "It [main] shall be defined [...] or in some other
>>implementation-defined manner."
>
> If plain "implementation-defined" is not supposed to have the same
> meaning as "implementation-defined baheviour", then its usage in the
> standard is a defect, because, not being defined, it can mean anything.

Well, you have to start somewhere, taking certain words an terms as
axioms. You can't define anything witout a language to write the
definitions with. The intuitive meaning of "implementation-defined"
is "defined by the implementation", which seems pretty straightforward
and clear to me (and now define "define" and "implementation"...).

>>> The text we are talking about is neither a syntax rule nor part of a
>>> constraint. So, where did you get the idea about the necessity of a
>>> diagnostic if void main is not supported?
>>
>> 3.8 constraint: restriction, either syntactic or semantic, by which
>> the exposition of language elements is to be interpreted
>>
>>Certainly, the definition of the startup function is a language
>>element, and 5.1.2.2.1 imposes restrictions upon it.
>

> I can't see any point in playing semantic games. A "constraint" in the
> standard is a paragraph *explicitly* labelled "Constraints".

Where in the standard does it say so? It seems reasonable to me to
assume that paragraphs labelled "Constraints" are intended to describe
constraints, but that's all.

-- Niklas


Chris Torek

unread,
Sep 28, 2000, 3:00:00 AM9/28/00
to
>In comp.std.c, Dan Pop <Dan...@cern.ch> writes:
>> I can't see any point in playing semantic games. A "constraint" in the
>> standard is a paragraph *explicitly* labelled "Constraints".

In article <8qv762$14v6d$1...@hades.rz.uni-sb.de>


Niklas Matthies <matt...@fsinfo.cs.uni-sb.de> writes:
>Where in the standard does it say so? It seems reasonable to me to
>assume that paragraphs labelled "Constraints" are intended to describe
>constraints, but that's all.

N2620 section 3.18, "undefined behavior", says, in part:

[#2] If a ``shall'' or ``shall not'' requirement that
appears outside of a constraint is violated, the behavior is
undefined.

For a "shall" or "shall not" to appear "outside of a constraint",
constraints must be somehow bounded. Thus this section:

>>> 3.8 constraint: restriction, either syntactic or semantic, by which
>>> the exposition of language elements is to be interpreted

has to be limited (otherwise all "shall"s and "shall not"s would be
inside their own, self-created constraints). It seems as though the
only sensible boundary is "paragraphs labelled `constraints'", and
that seems to be how the C standards have always been interpreted.

James Kuyper

unread,
Sep 28, 2000, 3:00:00 AM9/28/00
to
Chris Torek wrote:
...

> inside their own, self-created constraints). It seems as though the
> only sensible boundary is "paragraphs labelled `constraints'", and
> that seems to be how the C standards have always been interpreted.

Agreed - but the standard doesn't actually say so.

Barry Margolin

unread,
Sep 28, 2000, 3:00:00 AM9/28/00
to
In article <39D33A0B...@wizard.net>,

The standard is intended to be interpreted by humans with some amount of
common sense, not automatons who require obvious things spelled out for
them.

Larry Weiss

unread,
Sep 28, 2000, 3:00:00 AM9/28/00
to
Barry Margolin wrote:
>
> In article <39D33A0B...@wizard.net>,
> James Kuyper <kuy...@wizard.net> wrote:
> >Chris Torek wrote:
> >...
> >> inside their own, self-created constraints). It seems as though the
> >> only sensible boundary is "paragraphs labelled `constraints'", and
> >> that seems to be how the C standards have always been interpreted.
> >
> >Agreed - but the standard doesn't actually say so.
>
> The standard is intended to be interpreted by humans with some amount
> of common sense, not automatons who require obvious things spelled out
> for them.
>

A slippery slope, there, indeed.... <g>

Thomas...@cologne.de

unread,
Sep 28, 2000, 3:00:00 AM9/28/00
to
Douglas A. Gwyn <gw...@arl.army.mil> wrote:

>Of course, in comp.std.c we assume that participants
>understand the difference between a strictly conforming
>program, which does not exceed the minimal guarantees
>for what a conforming implementation must support, and
>a conforming program, which just happens to be accepted
>by *some* conforming implementation.

Is

PROGRAM MAIN
PRINT *,'HELLO, WORLD!'
END

a conforming C program after I've hacked my personal tools to try
the Fortran compiler after it has received too many syntax errors?

Paul Jarc

unread,
Sep 28, 2000, 3:00:00 AM9/28/00
to
Thomas...@cologne.de writes:
> Is
>
> PROGRAM MAIN
> PRINT *,'HELLO, WORLD!'
> END
>
> a conforming C program after I've hacked my personal tools to try
> the Fortran compiler after it has received too many syntax errors?

Yes. "Too many" could be 1, if you like, or you could even start with
Fortran and fall back to C, and still have a conforming C
implementation, as long as no Fortran program could also be a C
program.


paul

Dan Pop

unread,
Sep 28, 2000, 3:00:00 AM9/28/00
to
In <8qvlh5$2rs$1...@mvmap66.ciw.uni-karlsruhe.de> Thomas...@cologne.de writes:

>Douglas A. Gwyn <gw...@arl.army.mil> wrote:
>
>>Of course, in comp.std.c we assume that participants
>>understand the difference between a strictly conforming
>>program, which does not exceed the minimal guarantees
>>for what a conforming implementation must support, and

>>a conforming program, which just happens to be accepted
>>by *some* conforming implementation.


>
>Is
>
> PROGRAM MAIN
> PRINT *,'HELLO, WORLD!'
> END
>
>a conforming C program after I've hacked my personal tools to try
>the Fortran compiler after it has received too many syntax errors?

Of course it's a conforming C program. You don't even have to hack your
tools for that:

ues5:~/tmp 225> cat test.f


PROGRAM MAIN
PRINT *,'HELLO, WORLD!'
END

ues5:~/tmp 226> gcc -ansi -pedantic test.f -lf2c
ues5:~/tmp 227> ./a.out
HELLO, WORLD!

Phil Tregoning

unread,
Sep 28, 2000, 3:00:00 AM9/28/00
to

Dan Pop <Dan...@cern.ch> wrote in article
<8qvnfk$2ke$1...@sunnews.cern.ch>...
> In <8qvlh5$2rs$1...@mvmap66.ciw.uni-karlsruhe.de> Thomas...@cologne.de
writes:


>
> >
> >Is
> >
> > PROGRAM MAIN
> > PRINT *,'HELLO, WORLD!'
> > END
> >
> >a conforming C program after I've hacked my personal tools to try
> >the Fortran compiler after it has received too many syntax errors?
>
> Of course it's a conforming C program. You don't even have to hack your
> tools for that:
>
> ues5:~/tmp 225> cat test.f
> PROGRAM MAIN
> PRINT *,'HELLO, WORLD!'
> END
> ues5:~/tmp 226> gcc -ansi -pedantic test.f -lf2c
> ues5:~/tmp 227> ./a.out
> HELLO, WORLD!
>

I find it hard to believe a diagnostic isn't
required for that, which would make gcc as
you invoked it not a C compiler :)

Phil T

Douglas A. Gwyn

unread,
Sep 28, 2000, 3:00:00 AM9/28/00
to
Niklas Matthies wrote:
> ... I believe the standard just is not clear enough to allow a

> definite answer to the question of whether the addition of ";
> or in some other implementation-defined manner" has any effect.

It is meant as encouragement for implementations to document
other forms of main that they commit to support.

Larry Weiss

unread,
Sep 28, 2000, 3:00:00 AM9/28/00
to
"Douglas A. Gwyn" wrote:
> Niklas Matthies wrote:
> > ... I believe the standard just is not clear enough to allow a

> > definite answer to the question of whether the addition of ";
> > or in some other implementation-defined manner" has any effect.
>
> It is meant as encouragement for implementations to document
> other forms of main that they commit to support.

Seems more appropriate as a footnote than as normative text if that's
all there is to its rationale. A different placement (as a footnote)
and some simple rewording would do wonders.

- Larry Weiss

Douglas A. Gwyn

unread,
Sep 28, 2000, 3:00:00 AM9/28/00
to
Chris Torek wrote:
> ... I hardly think implementors need such a hint.)

In our experience, the hint is necessary in order to encourage
inclusion *in the C standards conformance document* a description
of additional forms of main that a conforming implementation
chooses to accept. So while the denotation is the same the
connotation is different.

Dan Pop

unread,
Sep 28, 2000, 3:00:00 AM9/28/00
to

No problem. Add the -v option and you'll get a bunch of diagnostics :-)

Clive D.W. Feather

unread,
Sep 28, 2000, 3:00:00 AM9/28/00
to
In article <8qttkk$4t0$1...@sunnews.cern.ch>, Dan Pop <Dan...@cern.ch>
writes

>If plain "implementation-defined" is not supposed to have the same
>meaning as "implementation-defined baheviour", then its usage in the
>standard is a defect, because, not being defined, it can mean anything.

This is not true: it is a combination - using a common English syntactic
form - of a technical term "implementation" and a common word "defined".
Alternatively, have you checked ISO 2382-1 ?

>I can't see any point in playing semantic games. A "constraint" in the

>standard is a paragraph *explicitly* labelled "Constraints". It is to
>such paragraphs that the definition of "diagnostic" makes reference.

Agreed.

--
Clive D.W. Feather | Internet Expert | Work: <cl...@demon.net>
Tel: +44 20 8371 1138 | Demon Internet | Home: <cl...@davros.org>
Fax: +44 20 8371 1037 | Thus plc | Web: <http://www.davros.org>
Written on my laptop; please observe the Reply-To address

Clive D.W. Feather

unread,
Sep 28, 2000, 3:00:00 AM9/28/00
to
In article <1B571D2324C62B9C.2CE3D971...@lp.airnew
s.net>, Larry Weiss <l...@airmail.net> writes
>And it should be promptly removed from the Standard.
>
>Especially since its champion can't recall any rationale for
>adding it:
>
> "[Seriously, it was something that I proposed, though I don't now
> remember what led me to do so.]" - Clive D.W. Feather

That doesn't mean there wasn't an accepted rationale at the time, just
that I can't remember - at this remove - what it was. I haven't even
looked in the Rationale draft yet.

>That additional sentence clause is wrecking havoc over in c.l.c as
>"evidence" that void main() is Standard C afterall, when it is no
>such thing, but the waters have been muddied just enough that those
>proponents of void main() are now concocting all sorts of elaboration
>to justify that unwarranted assertion.

Then they are spouting nonsense and need to learn how to read properly.
Any such argument ought to be easy enough to destroy.

Clive D.W. Feather

unread,
Sep 28, 2000, 3:00:00 AM9/28/00
to
In article <0438132DA4BEF363.21CF2173...@lp.airnew

s.net>, Larry Weiss <l...@airmail.net> writes
>It may be benign, but then again
>why include it? Is there a precedent for adding such "padding" ?

If you look carefully, you can find plenty of such "padding". Um, to
pick a random example, 6.7.5 paragraph 6, second sentence.

Clive D.W. Feather

unread,
Sep 28, 2000, 3:00:00 AM9/28/00
to
In article <8qtj86$t3t$1...@sunnews.cern.ch>, Dan Pop <Dan...@cern.ch>
writes

>>"implementation-defined" does not mean "documented by the
>>implementation".
>
>Has the following definition been dropped/changed in C99?
[...]

No. You are confusing logical-if with logical equivalence.

"implementation-defined" implies "documented by the implementation",
because the latter is a requirement of the former. Nonetheless, it is
possible for something to be documented without being implementation-
defined. Hence my statement.

>>>A compiler is not *required*
>>>by the standard to define void main any more than it is required to
>>>define signed integer arithmetic overflow.
>>
>>Correct.
>>
>>>So, the effect of "or in some other implementation-defined manner" is
>>>void and null :-)
>>
>>Wrong.
>
>Why?

First reason: because your logic includes errors, so "So" is wrong. One
break in the chain is enough.

But, second reason: if the implementation defines such an interface and
the program uses it, *the program does not invoke undefined behaviour*
by doing so.

In other words:

#include <stdio.h>
void main (void)
{
printf ("Hello world\n");
}

On C89, or an implementation not defining void main (void) as allowed,
this is undefined and the program can print any old rubbish. On a C99
implementation defining void main(void) as allowed, the programmer then
has a batch of guarantees she can rely on (basically, the rest of the
Standard).

Consider __STDC_IEC_559__. Surely this is useless on just the same
grounds as you claim ? Using anything it specifies is undefined
behaviour, so the implementation could define it to work anyway. What's
the difference ?

Clive D.W. Feather

unread,
Sep 28, 2000, 3:00:00 AM9/28/00
to
In article <8qtt2d$4c1$1...@sunnews.cern.ch>, Dan Pop <Dan...@cern.ch>
writes

>I definitely agree with this. What I don't understand is how to
>interpret "or in some other implementation-defined manner" in a manner
>which is consistent with the rest of the standard. Everywhere else in
>the standard, "implementation-defined" means that each and every
>implementation has to document its choice.

Right: the implementation has to document the list of interfaces that it
accepts.

>With the clause under debate, it seems that void main is either undefined
>behaviour or implementation-defined behaviour. This doesn't make any
>sense to me.

For a documented interface, all the other requirements of the Standard
apply. For an undocumented one, none of them do.

Consider the type int8_t. It is implementation-defined (actually,
there's no specific requirement to document it, so it's unspecified, but
the only difference *is* the requirement to document) whether this is
available or not. So, to quote you "it seems that [it] is either
undefined or [unspecified] behaviour. This doesn't make any sense to
me."

Of course, the point is that the existence of int8_t has a number of
implications. The same is true here.

Clive D.W. Feather

unread,
Sep 28, 2000, 3:00:00 AM9/28/00
to
In article <8qv51p$i03$1...@elf.bsdi.com>, Chris Torek <to...@elf.bsdi.com>
writes

>(They do not say this, but suppose they had.) One thing any
>implementation is permitted to do with undefined behavior is --
>surprise! -- to define it! ...

"If main is declared with a return type of void, the compiler will
exchange the meanings of the + and - operators throughout the
program."

>I conclude that this clause is meaningless, and might as well be
>ignored. (At most, the clause is a hint: "Gee, implementors, you
>might want to think about defining additional forms of main for
>historical compatibility with the compilers that came with your

>systems before ANSI C existed." I hardly think implementors need
>such a hint.)

You would be surprised. In the past I've had trouble even getting hold
of stuff that's supposed to be implementation-defined.

>(Perhaps most vendors historically
>preferred expending many man-months of effort on extensions and
>never once even *hinting* that said vendor-specific extensions
>existed. :-)

Just how much effort is required on typical systems to make void main
work ? Quite often none, provided that you're happy for strange things
to happen during the exit process (which brings us back to the
difference between implementation-defined and just-happens-to-be-
documented).

Douglas A. Gwyn

unread,
Sep 28, 2000, 3:00:00 AM9/28/00
to
Larry Weiss wrote:
> Seems more appropriate as a footnote than as normative text if that's
> all there is to its rationale. A different placement (as a footnote)
> and some simple rewording would do wonders.

I don't know what "wonders" you have in mind. C99 introduced
a new subclause heading for "Recommended practice", which is
better than using a footnote for such things. However, we
wanted to more strongly encourage this aspect of documentation.

Larry Weiss

unread,
Sep 28, 2000, 3:00:00 AM9/28/00
to


Then why didn't you word it more clearly?

"or in some other implementation-defined manner"

might have been

"or in some other manner clearly documented by the implementation"

Or is my wording not politcally correct?

- Larry Weiss

Larry Weiss

unread,
Sep 28, 2000, 3:00:00 AM9/28/00
to
"Douglas A. Gwyn" wrote:
> Larry Weiss wrote:
> > Seems more appropriate as a footnote than as normative text if that's
> > all there is to its rationale. A different placement (as a footnote)
> > and some simple rewording would do wonders.
>
> I don't know what "wonders" you have in mind. C99 introduced
> a new subclause heading for "Recommended practice", which is
> better than using a footnote for such things. However, we
> wanted to more strongly encourage this aspect of documentation.

I thought that sort of thing (strongly encouraging excellence in
implementation) was left to the marketplace, and not a burden that
the C Standard took upon itself.

- Larry Weiss

Dan Pop

unread,
Sep 28, 2000, 3:00:00 AM9/28/00
to

>But, second reason: if the implementation defines such an interface and
>the program uses it, *the program does not invoke undefined behaviour*
>by doing so.

What about a program that causes signed integer arithmetic overflow and
the implementation defines the behaviour of signed integer arithmetic
overflow?

Is it no longer possible to decide whether a program invokes undefined
behaviour or not, based exclusively on the text of the standard?

Larry Weiss

unread,
Sep 28, 2000, 3:00:00 AM9/28/00
to
"Douglas A. Gwyn" wrote:
> C99 introduced a new subclause heading for "Recommended practice",
> which is better than using a footnote for such things.

Is "Recommended practice" section text normative in C99?

- Larry Weiss

James Kuyper

unread,
Sep 28, 2000, 3:00:00 AM9/28/00
to

<rant>That's bad design. Most people act like "automatons who require
obvious things spelled out for them", at least every once in awhile.
More to the point, common sense means different things to different
people. A standard that's written to depend upon common sense isn't a
standard, it's a guideline. This isn't a novel, or a shopping list, or
advertising copy that we're talking about! It's a international standard
governing a highly technical subject, which calls for a much higher
level of precision.</rant>

I do think that a statement somewhere (probably in the definition of
'constraint') to the effect that only the rules explicitly labeled as
'constraints' are in fact constraints would improve the standard (unless
that would be a false statement). However, I don't think it's a big
issue; this is only the first time in several years of following both
the comp.std.c and comp.std.c++ newsgroups that I've seen anyone be
confused about how to identify a constraint.

Douglas A. Gwyn

unread,
Sep 28, 2000, 3:00:00 AM9/28/00
to
Larry Weiss wrote:
> Is "Recommended practice" section text normative in C99?

How could it be?

John Rickard

unread,
Sep 29, 2000, 3:00:00 AM9/29/00
to
James Kuyper <kuy...@wizard.net> wrote:
: I do think that a statement somewhere (probably in the definition of

: 'constraint') to the effect that only the rules explicitly labeled as
: 'constraints' are in fact constraints would improve the standard (unless
: that would be a false statement). However, I don't think it's a big
: issue; this is only the first time in several years of following both
: the comp.std.c and comp.std.c++ newsgroups that I've seen anyone be
: confused about how to identify a constraint.

Well, I was confused about whether the rule in C90 7.6.1.1 about the
contexts where setjmp could appear was a constraint; it was in a
paragraph labelled "Environmental constraint". C99 (or at least n869)
now labels the rule "Environmental limits" and adds "If the invocation
appears in any other context, the behavior is undefined", which makes
it fairly clear that it's not a constraint.

--
John Rickard <John.R...@virata.com>

Larry Weiss

unread,
Sep 29, 2000, 3:00:00 AM9/29/00
to

"recommended practice" is defined by the Standard:

General
3. Terms and definitions
3.17
[#1] recommended practice
specifications that are strongly recommended as being in
keeping with the intent of the standard, but that may be
impractical for some implementations


"normative" text is explicitly limited by the Standard:

Foreward
[#2] International Standards are drafted in accordance with
the rules given in the ISO/IEC Directives, Part 3.
Accordingly, annexes F and I form a normative part of this
standard; this foreword, the introduction, notes, footnotes,
examples, annexes A, B, C, D, E, G, H, J, K, the
bibliography, and the index are for information only.


Where does that leave "Recommended practice" text?

It seems to me that "Recommended practice" is indeed normative
(since it is not excluded in the definition of "normative" in the
foreward) although by definition only "strongly recommended".

Here's an example of a "Recommended practice" section:

6.4.4.2 Floating constants
. . .
Recommended practice
[#5] The implementation should produce a diagnostic message
if a hexadecimal constant cannot be represented exactly in
its evaluation format; the implementation should then
proceed with the translation of the program.

So it seems clear to me that following that example any
"strongly recommended" practices that pertain to section
5.1.2.2.1 should have been in the form of a "Recommended practice",
including the sentence clause under discussion in this thread.

- Larry Weiss

Niklas Matthies

unread,
Sep 29, 2000, 3:00:00 AM9/29/00
to
In comp.std.c, Barry Margolin <bar...@genuity.net> writes:
> In article <39D33A0B...@wizard.net>,
> James Kuyper <kuy...@wizard.net> wrote:
>>Chris Torek wrote:
>>...
>>> inside their own, self-created constraints). It seems as though the
>>> only sensible boundary is "paragraphs labelled `constraints'", and
>>> that seems to be how the C standards have always been interpreted.
>>
>>Agreed - but the standard doesn't actually say so.
>
> The standard is intended to be interpreted by humans with some amount of
> common sense, not automatons who require obvious things spelled out for
> them.

I believe a large amount of "common sense" is needed to come to such a
conclusion without any doubts remaining. It seems that interpretations
like the above are rather part of a folklore of the standard committee
member community, and those that communicate with them. But it's not
something easily comprehended or even necessarily aggredd upon by some
independend reader of the standard text. Of course the standard has to
rely on some "outside" knowledge and common use of words. But which
parts of the standard wordings constitute a 'constraint' (as a formal
concept in the standard) is not something that can be derived from
common sense, if the very definition of 'constraint' in the standard
does not provide further hints.

-- Niklas

Niklas Matthies

unread,
Sep 29, 2000, 3:00:00 AM9/29/00
to
In comp.std.c, Clive D.W. Feather <cl...@on-the-train.demon.co.uk> writes:
[...]

> But, second reason: if the implementation defines such an interface and
> the program uses it, *the program does not invoke undefined behaviour*
> by doing so.

3.4.3
undefined behavior
behavior, upon use of a nonportable or erroneous program construct
or of erroneous data, for which this International Standard imposes
no requirements

Certainly "void main(void) { ... }" is a nonportable program
construct. So if it's use doesn't invoke undefined behaviour, there
must be a requirement that the standard imposes on its behaviour.
It is not at all clear to me what could be considered to be such a
requirement, and how to decide, by reading the standard, if a specific
requirement stated in the standard applies to this "program construct"
(whatever the latter is meant to be, exactly).

-- Niklas

Nick Maclaren

unread,
Sep 29, 2000, 3:00:00 AM9/29/00
to
In article <8r2jv8$18hsh$1...@hades.rz.uni-sb.de>,

Niklas Matthies <matt...@fsinfo.cs.uni-sb.de> wrote:
>
>I believe a large amount of "common sense" is needed to come to such a
>conclusion without any doubts remaining. It seems that interpretations
>like the above are rather part of a folklore of the standard committee
>member community, and those that communicate with them. But it's not
>something easily comprehended or even necessarily aggredd upon by some
>independend reader of the standard text. Of course the standard has to
>rely on some "outside" knowledge and common use of words. But which
>parts of the standard wordings constitute a 'constraint' (as a formal
>concept in the standard) is not something that can be derived from
>common sense, if the very definition of 'constraint' in the standard
>does not provide further hints.

That is an understatement. I can witness that a large amount of
the interpretation of the standard is held to imply different things
by different members of the committee.

The C standard is in desperate need of being made more precise,
but unfortunately most of the people who hold this viewpoint have
dropped out. A few aspects (e.g. sequence points) are agreed to
be in need of attention, but the majority of problem areas aren't.


Regards,
Nick Maclaren,
University of Cambridge Computing Service,
New Museums Site, Pembroke Street, Cambridge CB2 3QG, England.
Email: nm...@cam.ac.uk
Tel.: +44 1223 334761 Fax: +44 1223 334679

Larry Jones

unread,
Sep 29, 2000, 3:00:00 AM9/29/00
to
Larry Weiss (l...@airmail.net) wrote:
>
> Is "Recommended practice" section text normative in C99?

Yes and no. It generally (always?) appears in a normative element, but
it does not contain any requirements that must be satisfied in order to
conform to the standard.

-Larry Jones

I'm so disappointed. -- Calvin

Clive D.W. Feather

unread,
Sep 29, 2000, 3:00:00 AM9/29/00
to
In article <8qtm87$12eg8$1...@hades.rz.uni-sb.de>, Niklas Matthies
<matt...@fsinfo.cs.uni-sb.de> writes
>The standard defines "implementation-defined behavior" as "unspecified
>behavior where each implementation documents how the choice is made".
>It doesn't specify at all what kinds of situations this can apply to,
>and of course if's are allowed ("if <condition>, then the behaviour is
>implementation-defined"). And, unless the standard imposes further
>requirements upon a certain construct in a certain situation, the
>implementation may choose to crash ("terminate abnormally") the
>program in that situation, if the standard has tagged the construct in
>that situation as "implementation-defined behavior", as long as it
>(the implementation) documents this behaviour.

Uh, not true:

3.4.4
[#1] unspecified behavior
behavior where this International Standard provides two or
more possibilities and imposes no further requirements on
which is chosen in any instance

Plus:

4
[#3] A program that is correct in all other aspects,
operating on correct data, containing unspecified behavior
shall be a correct program and act in accordance with
5.1.2.3.

Implementation-defined behaviour is limited to an explicit list of
choices, and crashing is definitely not allowed.

Clive D.W. Feather

unread,
Sep 29, 2000, 3:00:00 AM9/29/00
to
In article <wOs*s9...@news.cam.virata.com>, John Rickard
<j...@255.255.255.192> writes

>Well, I was confused about whether the rule in C90 7.6.1.1 about the
>contexts where setjmp could appear was a constraint; it was in a
>paragraph labelled "Environmental constraint". C99 (or at least n869)
>now labels the rule "Environmental limits" and adds "If the invocation
>appears in any other context, the behavior is undefined", which makes
>it fairly clear that it's not a constraint.

Indeed - those contexts are required to work (because setjmp may involve
magic of various kinds) but anything else is just your good luck.

Clive D.W. Feather

unread,
Sep 29, 2000, 3:00:00 AM9/29/00
to
In article <8r0fmj$cp7$1...@sunnews.cern.ch>, Dan Pop <Dan...@cern.ch>
writes

>>But, second reason: if the implementation defines such an interface and
>>the program uses it, *the program does not invoke undefined behaviour*
>>by doing so.
>
>What about a program that causes signed integer arithmetic overflow and
>the implementation defines the behaviour of signed integer arithmetic
>overflow?

Sorry, I don't follow your meaning. Unless I've overlooked something,
the behaviour of signed integer arithmetic overflow isn't
"implementation-defined behaviour".

>Is it no longer possible to decide whether a program invokes undefined
>behaviour or not, based exclusively on the text of the standard?

It never was. Whether 12345 * 10 is undefined depends on the
implementation.

Larry Weiss

unread,
Sep 29, 2000, 3:00:00 AM9/29/00
to
"Clive D.W. Feather" wrote:
> Larry Weiss <l...@airmail.net> writes
> >It may be benign, but then again
> >why include it? Is there a precedent for adding such "padding" ?
>
> If you look carefully, you can find plenty of such "padding". Um, to
> pick a random example, 6.7.5 paragraph 6, second sentence.

At least that sentence begins "Thus, " as a warning that what
follows may not be anything more than an exposition in derivation.

- Larry Weiss

Douglas A. Gwyn

unread,
Sep 29, 2000, 3:00:00 AM9/29/00
to
Niklas Matthies wrote:

> In comp.std.c, Clive D.W. Feather <cl...@on-the-train.demon.co.uk> writes:
> > But, second reason: if the implementation defines such an interface and
> > the program uses it, *the program does not invoke undefined behaviour*
> > by doing so.
> 3.4.3
> undefined behavior
> behavior, upon use of a nonportable or erroneous program construct
> or of erroneous data, for which this International Standard imposes
> no requirements

For C89, void main(void) did indeed invoke undefined behavior,
but for C99, it is as Clive said. It is a nonportable construct
for which the C99 standard *does* impose a requirement, albeit
merely that the implementation document it.

Dan Pop

unread,
Sep 29, 2000, 3:00:00 AM9/29/00
to
In <Fid3w$CmpL1...@on-the-train.demon.co.uk> "Clive D.W. Feather" <cl...@on-the-train.demon.co.uk> writes:

>In article <8r0fmj$cp7$1...@sunnews.cern.ch>, Dan Pop <Dan...@cern.ch>

>writes
>>>But, second reason: if the implementation defines such an interface and
>>>the program uses it, *the program does not invoke undefined behaviour*
>>>by doing so.
>>

>>What about a program that causes signed integer arithmetic overflow and
>>the implementation defines the behaviour of signed integer arithmetic
>>overflow?
>
>Sorry, I don't follow your meaning. Unless I've overlooked something,
>the behaviour of signed integer arithmetic overflow isn't
>"implementation-defined behaviour".

The logic is quite simple: the behaviour of void main isn't
"implementation-defined behaviour" either. But an implementation is
allowed to define any of these two. So, is there any difference between
the status of a program defining void main and that of a program causing
signed integer arithmetic overflow?

>>Is it no longer possible to decide whether a program invokes undefined
>>behaviour or not, based exclusively on the text of the standard?
>
>It never was. Whether 12345 * 10 is undefined depends on the
>implementation.

I was thinking about a program that does

int i = INT_MAX;
i++;

Is it no longer possible to say that this program invokes undefined
behaviour, because an implementation *might* define signed integer
arithmetic overflow? How is that different from a program defining
void main?

Dan Pop

unread,
Sep 29, 2000, 3:00:00 AM9/29/00
to
In <39D4F1D4...@arl.army.mil> "Douglas A. Gwyn" <gw...@arl.army.mil> writes:

>For C89, void main(void) did indeed invoke undefined behavior,
>but for C99, it is as Clive said. It is a nonportable construct
>for which the C99 standard *does* impose a requirement, albeit
>merely that the implementation document it.

How does C99 impose the requirement of documenting void main?
Is an implementation that supports void main but doesn't document it
non-conforming? Is an implementation that doesn't support it at all
non-conforming?

void main being undefined behaviour, there is absolutely no requirement
to document it, whether it is supported or not.

The "or in some other implementation-defined manner" has ZERO normative
powers, despite being in the normative part of the standard.

Douglas A. Gwyn

unread,
Sep 30, 2000, 2:23:33 AM9/30/00
to
Dan Pop wrote:
> int i = INT_MAX;
> i++;
> Is it no longer possible to say that this program invokes undefined
> behaviour, because an implementation *might* define signed integer
> arithmetic overflow? How is that different from a program defining
> void main?

The difference is that even if an implementation takes it upon
itself to define the behavior of this sample code, that does
not qualify as "implementation-defined behavior" within the
context of the C standard. Defining void main(void) as an
accepted interface does so qualify, in the 1999 C standard.

Fergus Henderson

unread,
Oct 2, 2000, 3:00:00 AM10/2/00
to
Barry Margolin <bar...@genuity.net> writes:

>James Kuyper <kuy...@wizard.net> wrote:
>>Chris Torek wrote:
>>...
>>> inside their own, self-created constraints). It seems as though the
>>> only sensible boundary is "paragraphs labelled `constraints'", and
>>> that seems to be how the C standards have always been interpreted.
>>
>>Agreed - but the standard doesn't actually say so.
>
>The standard is intended to be interpreted by humans with some amount of
>common sense, not automatons who require obvious things spelled out for
>them.

It seems to me to be common sense to assume that words have their
dictionary meaning unless otherwise stated.

--
Fergus Henderson <f...@cs.mu.oz.au> | "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh> | of excellence is a lethal habit"
PGP: finger f...@128.250.37.3 | -- the last words of T. S. Garp.

Fergus Henderson

unread,
Oct 2, 2000, 3:00:00 AM10/2/00
to
Larry Weiss <l...@airmail.net> writes:

>"Douglas A. Gwyn" wrote:


>>
>> Larry Weiss wrote:
>> > Is "Recommended practice" section text normative in C99?
>>

>> How could it be?

Well, the corresponding sections in the Ada 95 standard, which are
titled "Implementation advice", are normative. They have to be
normative, in fact, because although they don't impose any direct
requirements on the implementation, there is a documentation
requirement: it is "implementation defined" whether each
implementation advice section is obeyed, and so each implementation
must document whether it obeys each implementation advice section.

[...]


>It seems to me that "Recommended practice" is indeed normative
>(since it is not excluded in the definition of "normative" in the
>foreward) although by definition only "strongly recommended".

I agree with that analysis.

Nick Maclaren

unread,
Oct 2, 2000, 3:00:00 AM10/2/00
to

In article <8r9q88$pv2$1...@mulga.cs.mu.OZ.AU>,

f...@cs.mu.oz.au (Fergus Henderson) writes:
|> Larry Weiss <l...@airmail.net> writes:
|> >"Douglas A. Gwyn" wrote:
|> >> Larry Weiss wrote:
|> >> > Is "Recommended practice" section text normative in C99?
|> >>
|> >> How could it be?
|>
|> Well, the corresponding sections in the Ada 95 standard, which are
|> titled "Implementation advice", are normative. They have to be
|> normative, in fact, because although they don't impose any direct
|> requirements on the implementation, there is a documentation
|> requirement: it is "implementation defined" whether each
|> implementation advice section is obeyed, and so each implementation
|> must document whether it obeys each implementation advice section.

That is a good approach.

|> >It seems to me that "Recommended practice" is indeed normative
|> >(since it is not excluded in the definition of "normative" in the
|> >foreward) although by definition only "strongly recommended".
|>
|> I agree with that analysis.

Gug. We now have normative text (most of the standard), essential
informative text (e.g. footnote 84), normative informative text
(recommended practice), informative normative text (e.g. Annex G
when __STDC_IEC_559_COMPLEX__ is set), informative text (e.g. the
rationale), possibly normative text (e.g. the C90 DRs, SOME of
which apply to C99) and text which is normative by the omission
of the converse (e.g. the fact that the abstract machine uses a
single-threaded model).


Is it really so unreasonable to want a moratorium on any additions
or major changes to the C standard until and unless this situation
is improved?

Niklas Matthies

unread,
Oct 2, 2000, 3:00:00 AM10/2/00
to
In comp.std.c, Clive D.W. Feather <cl...@on-the-train.demon.co.uk> writes:
> In article <8qtm87$12eg8$1...@hades.rz.uni-sb.de>, Niklas Matthies
> <matt...@fsinfo.cs.uni-sb.de> writes
>>The standard defines "implementation-defined behavior" as "unspecified
>>behavior where each implementation documents how the choice is made".
>>It doesn't specify at all what kinds of situations this can apply to,
>>and of course if's are allowed ("if <condition>, then the behaviour is
>>implementation-defined"). And, unless the standard imposes further
>>requirements upon a certain construct in a certain situation, the
>>implementation may choose to crash ("terminate abnormally") the
>>program in that situation, if the standard has tagged the construct in
>>that situation as "implementation-defined behavior", as long as it
>>(the implementation) documents this behaviour.
>
> Uh, not true:
>
> 3.4.4
> [#1] unspecified behavior
> behavior where this International Standard provides two or
> more possibilities and imposes no further requirements on
> which is chosen in any instance

There is no implication by this definition that the two or more
possibilities provided by the standard are (a) explicit, and (b) if
they are explicit, are the only ones "provided".
In general, as far as this definition is concerned, "unspecified
behaviour" might include crashing, even if it is not an explicitly
specified possibility of behaviour.

(For those who doubt: For the behaviour of evaluating the expression
"INT_MAX + 1", does the standard "provide" the possibility that the
program raises SIGKILL (or, more generally, any implementation-defined
signal)? The only answer, lacking a more-than-common-sense explication
of what "provide" should mean, is 'yes', IMHO.)

> Plus:
>
> 4
> [#3] A program that is correct in all other aspects,
> operating on correct data, containing unspecified behavior
> shall be a correct program and act in accordance with
> 5.1.2.3.

I'm not sure this paragraph makes much sense. It seems to (a) define
the term "correct program" and (b) require "correct programs" to
respect 5.1.2.3 (which seems a tautology).

> Implementation-defined behaviour is limited to an explicit list of
> choices,

The definition of "implementation-defined behaviour" in the standard
doesn't say so, neither explicitly nor imlicitly, AFAICS.

> and crashing is definitely not allowed.

-- Niklas

Niklas Matthies

unread,
Oct 2, 2000, 3:00:00 AM10/2/00
to
In comp.std.c, Douglas A. Gwyn <gw...@arl.army.mil> writes:

> Niklas Matthies wrote:
>> In comp.std.c, Clive D.W. Feather <cl...@on-the-train.demon.co.uk> writes:
>> > But, second reason: if the implementation defines such an interface and
>> > the program uses it, *the program does not invoke undefined behaviour*
>> > by doing so.
>> 3.4.3
>> undefined behavior
>> behavior, upon use of a nonportable or erroneous program construct
>> or of erroneous data, for which this International Standard imposes
>> no requirements
>
> For C89, void main(void) did indeed invoke undefined behavior,
> but for C99, it is as Clive said. It is a nonportable construct
> for which the C99 standard *does* impose a requirement, albeit
> merely that the implementation document it.

The definition reads: "behavior [...] for which [the standard] imposes
no requirements". The requirement that the implementation documents it
is hardly a requirement on the behavior (in the sense that it would
limit the range of allowed behaviors), but on the implementation.
If you read this as being a requirement on the behavior, then I can go
one step further and say there always is, because there's always the
requirement that one behavior has to occur (i.e. the implementation,
for a given program run, has forcibly to choose some (one) behavior).
I think you are on very thin ice here.

-- Niklas

Barry Margolin

unread,
Oct 2, 2000, 3:00:00 AM10/2/00
to
In article <39D3E370...@wizard.net>,
James Kuyper <kuy...@wizard.net> wrote:

>Barry Margolin wrote:
>> The standard is intended to be interpreted by humans with some amount of
>> common sense, not automatons who require obvious things spelled out for
>> them.
>
><rant>That's bad design. Most people act like "automatons who require
>obvious things spelled out for them", at least every once in awhile.
>More to the point, common sense means different things to different
>people. A standard that's written to depend upon common sense isn't a
>standard, it's a guideline. This isn't a novel, or a shopping list, or
>advertising copy that we're talking about! It's a international standard
>governing a highly technical subject, which calls for a much higher
>level of precision.</rant>

But eventually you have to bottom out and resort to the reader's expected
knowledge of the subject area and the language the document is written in.
The document can't define every term it uses, because then it would be
circular and meaningless.

Regarding the use of the word "constraint", the standard, by its very
nature, is one big constraint (going by the dictionary definition). So
obviously, when something in the standard refers to something that violates
a constraint, it's almost certainly referring to the sections explicitly
labeled "constraint" rather than anything that the English language would
call a constraint, because if it meant the latter it would mean the entire
standard, and thus not really mean anything.

It would be nice if the authors of a standard could really write a document
that would stand up to the scrutiny of computer programmers, who are used
to spelling things out in excruciating detail. But as the member of an
ANSI technical committee, I can attest that it's an impossible task. You
try your best, but occasionally you slip up and use a technical term in its
non-technical sense, or forget to use the technical term that you'd defined
for a purpose, etc. Critical mistakes get caught and fixed during the
public review period (sort of like a beta test for standards), but often
the schedule doesn't permit all the minor errors to be found and fixed.
But we can count on the fact that the people writing compilers based on the
standard are humans, with the ability to recognize inconsistencies and work
them out logically -- and in cases where there isn't enough evidence to do
this, they can submit Defect Reports to get the standard clarified now and
fixed in the next revision.

--
Barry Margolin, bar...@genuity.net
Genuity, Burlington, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.

Barry Margolin

unread,
Oct 2, 2000, 3:00:00 AM10/2/00
to
In article <8r9nk6$of1$1...@mulga.cs.mu.OZ.AU>,

Fergus Henderson <f...@cs.mu.oz.au> wrote:
>Barry Margolin <bar...@genuity.net> writes:
>
>>James Kuyper <kuy...@wizard.net> wrote:
>>>Chris Torek wrote:
>>>...
>>>> inside their own, self-created constraints). It seems as though the
>>>> only sensible boundary is "paragraphs labelled `constraints'", and
>>>> that seems to be how the C standards have always been interpreted.
>>>
>>>Agreed - but the standard doesn't actually say so.
>>
>>The standard is intended to be interpreted by humans with some amount of
>>common sense, not automatons who require obvious things spelled out for
>>them.
>
>It seems to me to be common sense to assume that words have their
>dictionary meaning unless otherwise stated.

But if that leads to a nonsensical conclusion, common sense dictates
otherwise. According to the dictionary definition, the entire standard is
a constraint, in which case it makes no sense to distinguish constraint
violations from other deviations from the standard.

Douglas A. Gwyn

unread,
Oct 2, 2000, 3:00:00 AM10/2/00
to
Nick Maclaren wrote:
> Gug. We now have normative text (most of the standard), essential
> informative text (e.g. footnote 84), normative informative text
> (recommended practice), informative normative text (e.g. Annex G
> when __STDC_IEC_559_COMPLEX__ is set), informative text (e.g. the
> rationale), possibly normative text (e.g. the C90 DRs, SOME of
> which apply to C99) and text which is normative by the omission
> of the converse (e.g. the fact that the abstract machine uses a
> single-threaded model).

I disagree with your categorization.

> Is it really so unreasonable to want a moratorium on any additions
> or major changes to the C standard until and unless this situation
> is improved?

I honestly don't know how anyone could word a C standard that
would satisfy simultaneously you and most other clients for
the standard.

Douglas A. Gwyn

unread,
Oct 2, 2000, 3:00:00 AM10/2/00
to
Niklas Matthies wrote:
> In comp.std.c, Douglas A. Gwyn <gw...@arl.army.mil> writes:
> > For C89, void main(void) did indeed invoke undefined behavior,
> > but for C99, it is as Clive said. It is a nonportable construct
> > for which the C99 standard *does* impose a requirement, albeit
> > merely that the implementation document it.
> The definition [of "undefined behavior"] reads: "behavior [...]

> for which [the standard] imposes no requirements".

Yes, that's why void main(void) in C99 is not "undefined behavior"
-- it doesn't match the definition.

> I think you are on very thin ice here.

Not nearly as thin as most of the attempts at reinterpretation
one sees in this forum.

James Kuyper

unread,
Oct 2, 2000, 3:00:00 AM10/2/00
to
Niklas Matthies wrote:
>
> In comp.std.c, Clive D.W. Feather <cl...@on-the-train.demon.co.uk> writes:
...

> > 4
> > [#3] A program that is correct in all other aspects,
> > operating on correct data, containing unspecified behavior
> > shall be a correct program and act in accordance with
> > 5.1.2.3.
>
> I'm not sure this paragraph makes much sense. It seems to (a) define
> the term "correct program" and (b) require "correct programs" to
> respect 5.1.2.3 (which seems a tautology).

That's not a definition. Nor is it a tautology. The key point of that
paragraph is the term "unspecified behavior". Sure, a correct program
must respect 5.1.2.3; the point of that paragraph is that it is still a
correct program even if it contains unspecified behavior. That means
that unspecified behavior isn't a license to violate 5.1.2.3.

Implementation-defined behavior is defined to be unspecified behavior,
and therefore doesn't provide the same unlimited license that undefined
behavior does. Not being allowed to violate section 5.1.2.3 has some
pretty far-reaching implications. For instance:

...

James Kuyper

unread,
Oct 2, 2000, 3:00:00 AM10/2/00
to
Barry Margolin wrote:
...

> It would be nice if the authors of a standard could really write a document
> that would stand up to the scrutiny of computer programmers, who are used
> to spelling things out in excruciating detail. But as the member of an
> ANSI technical committee, I can attest that it's an impossible task. You

I fully respect how difficult that is. I've no expectation that the
standard can be perfect; it's written by human beings, not deities.
However, when a problem with the wording is pointed out, "How can we fix
it?" seems a more appropriate response than "You know what was meant,
there's no need to fix it."

Dan Pop

unread,
Oct 2, 2000, 9:25:51 PM10/2/00
to
In <39D90E48...@null.net> "Douglas A. Gwyn" <DAG...@null.net> writes:

>Niklas Matthies wrote:
>> In comp.std.c, Douglas A. Gwyn <gw...@arl.army.mil> writes:
>> > For C89, void main(void) did indeed invoke undefined behavior,
>> > but for C99, it is as Clive said. It is a nonportable construct
>> > for which the C99 standard *does* impose a requirement, albeit
>> > merely that the implementation document it.
>> The definition [of "undefined behavior"] reads: "behavior [...]
>> for which [the standard] imposes no requirements".
>
>Yes, that's why void main(void) in C99 is not "undefined behavior"
>-- it doesn't match the definition.

What are the requirements *imposed* on void main by C99?

Clive D.W. Feather

unread,
Oct 3, 2000, 3:00:00 AM10/3/00
to
In article <8ra3cl$1kv0t$1...@hades.rz.uni-sb.de>, Niklas Matthies
<matt...@fsinfo.cs.uni-sb.de> writes

>> 3.4.4
>> [#1] unspecified behavior
>> behavior where this International Standard provides two or
>> more possibilities and imposes no further requirements on
>> which is chosen in any instance
>
>There is no implication by this definition that the two or more
>possibilities provided by the standard are (a) explicit,

"this International Standard provides"
^^^^^^^^

>and (b) if
>they are explicit, are the only ones "provided".

Where the Standard provides a list of alternatives, they are always the
full list of possibilities unless it explicitly says otherwise.

>In general, as far as this definition is concerned, "unspecified
>behaviour" might include crashing, even if it is not an explicitly
>specified possibility of behaviour.

Wrong, both because of this and because of the bit I quoted from clause
4.

>(For those who doubt: For the behaviour of evaluating the expression
>"INT_MAX + 1", does the standard "provide" the possibility that the
>program raises SIGKILL (or, more generally, any implementation-defined
>signal)?

This expression involves an overflow, so the behaviour is *undefined*,
not unspecified.

>> 4
>> [#3] A program that is correct in all other aspects,
>> operating on correct data, containing unspecified behavior
>> shall be a correct program and act in accordance with
>> 5.1.2.3.
>
>I'm not sure this paragraph makes much sense. It seems to (a) define
>the term "correct program" and (b) require "correct programs" to
>respect 5.1.2.3 (which seems a tautology).

No, it states that a program containing unspecified behaviour is still
correct and must respect 5.1.2.3.

>> Implementation-defined behaviour is limited to an explicit list of
>> choices,
>
>The definition of "implementation-defined behaviour" in the standard
>doesn't say so, neither explicitly nor imlicitly, AFAICS.

3.4.1 and 3.4.4 say so.

Clive D.W. Feather

unread,
Oct 3, 2000, 3:00:00 AM10/3/00
to
In article <8r2ksb$18hsh$2...@hades.rz.uni-sb.de>, Niklas Matthies
<matt...@fsinfo.cs.uni-sb.de> writes

> 3.4.3
> undefined behavior
> behavior, upon use of a nonportable or erroneous program construct
> or of erroneous data, for which this International Standard imposes
> no requirements

*for which* ... no requirements.

>Certainly "void main(void) { ... }" is a nonportable program
>construct.

Accepted.

>So if it's use doesn't invoke undefined behaviour, there
>must be a requirement that the standard imposes on its behaviour.

There are two classes of implementation for this purpose; let's call
them VMA and VMU. All implementations have a conformance document, and
we can look at that. For a VMA implementation, this document says
something like "5.1.2.2.1: allows void main (void)", while for a VMU
implementation, it doesn't say that.

On a VMU implementation the above construct is undefined. No debate.

On a VMA implementation, there is a requirement that the standard
imposes on its behaviour. That requirement is: *everything* in the
Standard, with the exceptions of 5.1.2.2.1#2 and the first sentence of
5.1.2.2.3#1 (strictly speaking, these apply but are nugatory because
their controlling conditions don't apply).

>It is not at all clear to me what could be considered to be such a
>requirement, and how to decide, by reading the standard, if a specific
>requirement stated in the standard applies to this "program construct"
>(whatever the latter is meant to be, exactly).

All requirements apply to correct programs unless they say otherwise. On
a VMA implementation, a program using void main is a correct program (as
far as that is concerned).


Let me show you another example. The value of INT_MAX is implementation-
defined. There are two classes of implementation: SI and LI. The former
state that INT_MAX is 32767 and the latter that it is 65535 or greater.

int main (void)
{
return (12345 * 5) * 0;
}

On an LI implementation this is a correct program that returns 0 to the
environment. On an SI implementation this is undefined behaviour. To
reuse your own words with one edit:

Certainly "12345 * 5" is a nonportable program construct.
>So if its use doesn't invoke undefined behaviour,


>there must be a requirement that the standard imposes on its behaviour.
>It is not at all clear to me what could be considered to be such a
>requirement, and how to decide, by reading the standard, if a specific
>requirement stated in the standard applies to this "program construct"
>(whatever the latter is meant to be, exactly).

Could you please explain where the significant difference between these
two lies ?

Clive D.W. Feather

unread,
Oct 3, 2000, 3:00:00 AM10/3/00
to
In article <8r31vd$jmm$1...@sunnews.cern.ch>, Dan Pop <Dan...@cern.ch>

writes
>>>>But, second reason: if the implementation defines such an interface and
>>>>the program uses it, *the program does not invoke undefined behaviour*
>>>>by doing so.
>>>
>>>What about a program that causes signed integer arithmetic overflow and
>>>the implementation defines the behaviour of signed integer arithmetic
>>>overflow?
>>
>>Sorry, I don't follow your meaning. Unless I've overlooked something,
>>the behaviour of signed integer arithmetic overflow isn't
>>"implementation-defined behaviour".
>
>The logic is quite simple: the behaviour of void main isn't
>"implementation-defined behaviour" either.

The behaviour of void main isn't, but *whether void main is a supported
interface* **is**. See below.

>But an implementation is
>allowed to define any of these two.

True but irrelevant.

>So, is there any difference between
>the status of a program defining void main and that of a program causing
>signed integer arithmetic overflow?

Yes, because of the rules concerning main.

>I was thinking about a program that does
>

> int i = INT_MAX;
> i++;
>
>Is it no longer possible to say that this program invokes undefined
>behaviour, because an implementation *might* define signed integer
>arithmetic overflow?

This remains undefined, pure and simple.

>How is that different from a program defining
>void main?

Quite a lot.

Let's start again.

Program P1:

int main (int argc, char *argv [])
{
// Do lots of sensible things here
return 0;
}

is a "correct" program (assuming the comment doesn't hide any problems).
The Standard imposes a whole load of requirements on this program.

Program P2:

int main (void)
{
// Do the same things here
return 0;
}

is also a "correct" program. The Standard imposes exactly the same
requirements, *except* for the ones about argc and argv.

Now consider three implementations, IA, IB, and IC. These define - in
their conformance documents - extra interfaces for main():

IA: int main (int argc, char *argv [], char *envp []);
IB: void main (void);
IC: none

Now let's look at program P3:

int main (int argc, char *argv [], char *envp [])
{
// Do lots of sensible things here
return 0;
}

is a *correct* program when run on IA, but is undefined on IB and IC.
[There's nothing odd about "correct on one system, undefined on
another"; as I pointed out, 12345 * 10 has that property.] When it's run
on IA the Standard imposes *all* of its requirements except (possibly)
the ones about argc and argv.

Finally let's look at program P4:

void main (void)
{
// Do the same things here
return;
}

This is undefined on IA and IC, but it is a correct program on IB. The
Standard *still* imposes all its requirements, except for the ones about
argc and argv, and except for the one about the value returned from
main. And if I'd written the code to use exit() instead of return, even
this difference wouldn't have been significant.


This is the point:
* If the program uses a valid interface for main (), the Standard
imposes all the requirements we know and love, except for those parts
of 5.1.2.2 that don't apply to the specific interface.
* The valid interfaces for main() vary from implementation to
implementation.
* int (void) and int (int, char **) are always valid.

Clive D.W. Feather

unread,
Oct 3, 2000, 3:00:00 AM10/3/00
to
In article <8r37eh$mhv$1...@sunnews.cern.ch>, Dan Pop <Dan...@cern.ch>
writes
>In <39D4F1D4...@arl.army.mil> "Douglas A. Gwyn" <gw...@arl.army.mil>
>writes:
>
>>For C89, void main(void) did indeed invoke undefined behavior,
>>but for C99, it is as Clive said. It is a nonportable construct
>>for which the C99 standard *does* impose a requirement, albeit
>>merely that the implementation document it.
>
>How does C99 impose the requirement of documenting void main?

I don't agree with Doug here.

In C99 an implementation can choose to formally support void main or
not.

It chooses not It chooses to

It documents nothing; nothing It documents void main as applying
changes from C89. in 5.1.2.2.1. Programs that use
void main (void) are identical to
those that use int main (void),
except for how 5.1.2.2.3 applies.

>Is an implementation that supports void main but doesn't document it
>non-conforming? Is an implementation that doesn't support it at all
>non-conforming?

No.

>void main being undefined behaviour, there is absolutely no requirement
>to document it, whether it is supported or not.

But if it *is* documented, other requirements come into play.

>The "or in some other implementation-defined manner" has ZERO normative
>powers, despite being in the normative part of the standard.

Still wrong.

Nick Maclaren

unread,
Oct 3, 2000, 3:00:00 AM10/3/00
to
In article <39D90D54...@null.net>,

Douglas A. Gwyn <DAG...@null.net> wrote:
>Nick Maclaren wrote:
>> Gug. We now have normative text (most of the standard), essential
>> informative text (e.g. footnote 84), normative informative text
>> (recommended practice), informative normative text (e.g. Annex G
>> when __STDC_IEC_559_COMPLEX__ is set), informative text (e.g. the
>> rationale), possibly normative text (e.g. the C90 DRs, SOME of
>> which apply to C99) and text which is normative by the omission
>> of the converse (e.g. the fact that the abstract machine uses a
>> single-threaded model).
>
>I disagree with your categorization.

Noted. There are probably a zillion other, equally valid,
categorisations.

>> Is it really so unreasonable to want a moratorium on any additions
>> or major changes to the C standard until and unless this situation
>> is improved?
>
>I honestly don't know how anyone could word a C standard that
>would satisfy simultaneously you and most other clients for
>the standard.

Obviously, nothing is perfect, but the C standard is uniquely bad
in my (fairly extensive) experience. All of the following are
an order of magnitude better: Algol 68, ISO Pascal, Fortran 77,
Fortran 90, Ada 8x, Java, POSIX (1990), IBM MVT, IBM MVS, MPI 1,
MPI 2, and many others that I have looked at.

I get a fair number of users reporting compiler bugs to me, in
both Fortran and C. Now, if we exclude those that are never
tied down, my experience is something like the following (all
figures are VERY approximate guesses) for reports from experienced,
competent users:

Fortran 90 C
User error 50% 25%
Compiler/system error 35% 10%
Known ambiguity in standard 0% 30%
Unable to interpret standard 15% 35%

I know C a LOT better than I know Fortran 90, yet the latter
standard is VASTLY easier to interpret. And the difference is not
in the nature of the language, but in the way that the standard is
written.

It has been suggested that I follow up my queries and claims of
ambiguity with Defect Reports. I am not joking when I say that I
could locate a HUNDRED such problems that I have seen in actual
code within a week or so. I am still thinking about whether to
do that.

Niklas Matthies

unread,
Oct 3, 2000, 3:00:00 AM10/3/00
to
In comp.std.c, Clive D.W. Feather <cl...@on-the-train.demon.co.uk> writes:
> In article <8ra3cl$1kv0t$1...@hades.rz.uni-sb.de>, Niklas Matthies
> <matt...@fsinfo.cs.uni-sb.de> writes

>>> 3.4.4
>>> [#1] unspecified behavior
>>> behavior where this International Standard provides two or
>>> more possibilities and imposes no further requirements on
>>> which is chosen in any instance
>>
>>There is no implication by this definition that the two or more
>>possibilities provided by the standard are (a) explicit,
>
> "this International Standard provides"
> ^^^^^^^^
>>and (b) if
>>they are explicit, are the only ones "provided".
>
> Where the Standard provides a list of alternatives, they are always the
> full list of possibilities unless it explicitly says otherwise.

That seems to be true, but the definition of "unspecified behavior"
doesn't talk about providing an explicit list of alternatives of
possible behaviours, it just talks about providing "possibilities".
This is so vague that I can't see the (implicit) requirement that this
possibilities are presented as an explicit, exhausting list of
alternatives, instead of the possibilities that implicitly arise from
the standard text (as in the example I provided below).

I (now) know that your interpretation is probably what was intended by
the standardization committee members, but the standard text is far
from specifying this intent.

If I ask you, completely out of context, "does the standard provide
the possibility of an implementation-defined value being the result
of or an implementation-defined signal being raised upon signed
integer overflow?", would you really honestly answer "no, of course
not"?

>>In general, as far as this definition is concerned, "unspecified
>>behaviour" might include crashing, even if it is not an explicitly
>>specified possibility of behaviour.
>
> Wrong, both because of this and because of the bit I quoted from clause
> 4.
>
>>(For those who doubt: For the behaviour of evaluating the expression
>>"INT_MAX + 1", does the standard "provide" the possibility that the
>>program raises SIGKILL (or, more generally, any implementation-defined
>>signal)?
>
> This expression involves an overflow, so the behaviour is *undefined*,
> not unspecified.

In my reading, and as I explained, it matches the standard's
definition of "unspecified behavior". If you disagree, you'll have to
convincingly explain how to forcibly derive from the wording of the
standard that it doesn't match the definition, or violates some other
restriction of the standard.

>>> 4
>>> [#3] A program that is correct in all other aspects,
>>> operating on correct data, containing unspecified behavior
>>> shall be a correct program and act in accordance with
>>> 5.1.2.3.
>>
>>I'm not sure this paragraph makes much sense. It seems to (a) define
>>the term "correct program" and (b) require "correct programs" to
>>respect 5.1.2.3 (which seems a tautology).
>
> No, it states that a program containing unspecified behaviour is still
> correct and must respect 5.1.2.3.

Well, wth does this mean? What is a "correct program"? A strictly
conforming one? Or just a conforming one? If this paragraph weren't
there, would there be any way to conclude from the standard that
a program execution containing occurrences of unspecified behaviour
doesn't have to respect 5.1.2.3 because of these occurrences (as long
as the program's output doesn't depend on it)? Does "correct in all
other aspects" include that the output may not depend on unspecified
behavior, or does it not?

I can't make sense of this without further explanations, and, unless
I overlooked something, the standard doesn't further clarify this;
so I'd say it is defective.

>>> Implementation-defined behaviour is limited to an explicit list of
>>> choices,
>>
>>The definition of "implementation-defined behaviour" in the standard
>>doesn't say so, neither explicitly nor imlicitly, AFAICS.
>
> 3.4.1 and 3.4.4 say so.

I do not agree.

-- Niklas


Niklas Matthies

unread,
Oct 3, 2000, 3:00:00 AM10/3/00
to
In comp.std.c, Clive D.W. Feather <cl...@on-the-train.demon.co.uk> writes:
> In article <8r2ksb$18hsh$2...@hades.rz.uni-sb.de>, Niklas Matthies
> <matt...@fsinfo.cs.uni-sb.de> writes

>> 3.4.3
>> undefined behavior
>> behavior, upon use of a nonportable or erroneous program construct
>> or of erroneous data, for which this International Standard imposes
>> no requirements
>
> *for which* ... no requirements.
>
>>Certainly "void main(void) { ... }" is a nonportable program
>>construct.
>
> Accepted.
>
>>So if it's use doesn't invoke undefined behaviour, there
>>must be a requirement that the standard imposes on its behaviour.
>
> There are two classes of implementation for this purpose; let's call
> them VMA and VMU. All implementations have a conformance document, and
> we can look at that. For a VMA implementation, this document says
> something like "5.1.2.2.1: allows void main (void)", while for a VMU
> implementation, it doesn't say that.
>
> On a VMU implementation the above construct is undefined. No debate.
>
> On a VMA implementation, there is a requirement that the standard
> imposes on its behaviour. That requirement is: *everything* in the
> Standard, with the exceptions of 5.1.2.2.1#2 and the first sentence of
> 5.1.2.2.3#1 (strictly speaking, these apply but are nugatory because
> their controlling conditions don't apply).
[further good explanations snipped]

Ok, I see the point, and accept that (as far as 5.1.2.2.1 is
concerned).

>>It is not at all clear to me what could be considered to be such a
>>requirement, and how to decide, by reading the standard, if a specific
>>requirement stated in the standard applies to this "program construct"
>>(whatever the latter is meant to be, exactly).
>
> All requirements apply to correct programs unless they say otherwise.

Common sense would tell me that it is the other way round: A program
that respects all requirements is (then) correct. How do you tell
whether a program is correct before you know which requirements have
to apply?

> On a VMA implementation, a program using void main is a correct
> program (as far as that is concerned).

Since "correct program" seems to become a more and more important term
in this thread, we should define it. Do you mean by "correct program"
a program accepted by a specific conforming implementation, as long as
beeing run only under that specific implementation? If not, what else
exactly?

-- Niklas


It is loading more messages.
0 new messages