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

Quick C test - whats the correct answer???

4 views
Skip to first unread message

David C. M. Bilsby

unread,
Feb 9, 1995, 4:14:31 AM2/9/95
to
Hi,
Someone posed me this question recently, what is the answer of the below
segment of C code :

int main(void)
{
int i = 2;

i = i++;
return(i);
}

What is the correct asnwer returned, is it 2 or 3 ?

Cheers
David.

--
-----------------------------------------------------------------
| Image Processing Section | David Bilsby |
| email: bil...@signal.dra.hmg.gb | Defence Research Agency |
| | Room E306 |
| Tel: +44 (684) 896158 | St Andrews Road |
| Fax: +44 (684) 894384 | Malvern. WR14 3PS UK |
-----------------------------------------------------------------

Tanmoy Bhattacharya

unread,
Feb 9, 1995, 11:55:29 AM2/9/95
to
In article <3hcmdn$k...@signal.dra.hmg.gb>, bil...@signal.dra.hmg.gb (David C. M.

Bilsby) writes:
|> Hi,
|> Someone posed me this question recently, what is the answer of the below
|> segment of C code :
<snip>
|> i = i++;
<snip>

Sorry, i = i++; is anything but C. Please read the FAQ before posting.

This is one of the most FA FAQ Q! And one of the simplest. i = i++ in a C
program leads to absolutely undefined behaviour.

Cheers
Tanmoy
--
tan...@qcd.lanl.gov(128.165.23.46) DECNET: BETA::"tan...@lanl.gov"(1.218=1242)
Tanmoy Bhattacharya O:T-8(MS B285)LANL,NM87544-0285,USA H:#3,802,9 St,NM87545
Others see <gopher://yaleinfo.yale.edu:7700/00/Internet-People/internet-mail>,
<http://alpha.acast.nova.edu/cgi-bin/inmgq.pl>or<ftp://csd4.csd.uwm.edu/pub/
internetwork-mail-guide>. -- <http://nqcd.lanl.gov/people/tanmoy/tanmoy.html>
fax: 1 (505) 665 3003 voice: 1 (505) 665 4733 [ Home: 1 (505) 662 5596 ]

har...@linkage.com

unread,
Feb 9, 1995, 3:44:08 PM2/9/95
to
In <3hcmdn$k...@signal.dra.hmg.gb>, bil...@signal.dra.hmg.gb (David C. M. Bilsby) writes:
>Hi,
> Someone posed me this question recently, what is the answer of the below
>segment of C code :
>
>int main(void)
>{
> int i = 2;
>
> i = i++;
> return(i);
>}
>
> What is the correct asnwer returned, is it 2 or 3 ?
>
> Cheers
> David.
>

The correct answer is.... Both!

How i = i++ gets evaluated is implimentation defined. Compiler A is free to let the expression evaluate to 2, while compiler B is equally free to let it resolve to 3.

Because it's implimentation defined, to save your sanity, you should not know how your compiler handles it. Suppose, i=2;i = i++; resolves to 3 in version 4.0 of your compiler. Consequently your code works wonderfully. Eventually version 5.0 of the compiler comes out, unfortunatly i now equals 2. Boo hoo, your code breaks.

Harvey Rook
har...@linkage.com

Jake Donham

unread,
Feb 9, 1995, 4:47:42 PM2/9/95
to
"David" == David C M Bilsby <bil...@signal.dra.hmg.gb> affirms:

David> Hi, Someone posed me this question recently, what is the
David> answer of the below segment of C code :

David> int main(void) { int i = 2;
David> i = i++; return(i); }

David> What is the correct asnwer returned, is it 2 or 3 ?

The statement 'i = i++;' has undefined behavior, since i is modified
twice between sequence points. So there is no correct answer.

I can't figure out why people are so fascinated by this.

Jake

Dominic Feeley

unread,
Feb 9, 1995, 4:21:15 PM2/9/95
to
In article <3hcmdn$k...@signal.dra.hmg.gb>
bil...@signal.dra.hmg.gb "David C. M. Bilsby" writes:

> Subject: Quick C test - whats the correct answer???
>
> i = i++;


> What is the correct asnwer returned, is it 2 or 3 ?

There isn't a correct answer. See the FAQ, sections 4.1 and 4.2

Followups-to: misc.test

Regards,
Dominic.

--
---------------------------------------------------------------------------
- Dominic Feeley ( do...@dfdesign.demon.co.uk ) -
---------------------------------------------------------------------------

Ross Driedger

unread,
Feb 9, 1995, 11:29:02 PM2/9/95
to
bil...@signal.dra.hmg.gb (David C. M. Bilsby) wrote:
>>Hi,
>> Someone posed me this question recently, what is the answer of the below
>>segment of C code :

[chop]

David,

Doesn't the person who posed this question to you have a real life?
There are more important things to do in this world than wondering
about this gargabe. I think, by the frequency of "what does 'i = i++'
mean?" on this base that I'm going to see someone try that in the
real or academic world sooner or later.

Any earthquake in the vicinity of Lake Ontario will be result of someone
trying to pass this nonsense off as C code in front of me.

In the meantime tell that person to take a half decent course
in C. (and rent a real life if (s)he hasn't got one)

Ross Driedger
cs4g...@maccs.dcss.mcmaster.ca
(When I grow up I want to have a REAL net address!)

Albert Yale

unread,
Feb 9, 1995, 8:12:43 PM2/9/95
to
David C. M. Bilsby (bil...@signal.dra.hmg.gb) wrote:

: int main(void)


: {
: int i = 2;
:
: i = i++;
: return(i);
: }

: What is the correct asnwer returned, is it 2 or 3 ?

i say 3.

i = i so i = 2 then i is incremented to 3. simple. why? cuz ++ is a postfix
so evaluated last.

Al
--
100 little bugs in the code, | I check my email more often than my
100 little bugs, | answering machine.
fix a bug, compile again, | So if you wish to reach me, email at
101 little bugs in the code... | mat...@nyongwa.montreal.qc.ca

Dan Pop

unread,
Feb 10, 1995, 9:01:03 AM2/10/95
to
In <3hcmdn$k...@signal.dra.hmg.gb> bil...@signal.dra.hmg.gb (David C. M. Bilsby) writes:

>int main(void)
>{
> int i = 2;
>
> i = i++;
> return(i);
>}
>
> What is the correct asnwer returned, is it 2 or 3 ?
>

It's been such a long time since the last i=i++ thread... :-(

With the naive hope that I can prevent a new thread on this silly subject,
I'll post the relevant part of the c.l.c FAQ and recommend the interested
parties to read the _full_ FAQ.

4.2: Under my compiler, the code

int i = 7;
printf("%d\n", i++ * i++);

prints 49. Regardless of the order of evaluation, shouldn't it
print 56?

A: Although the postincrement and postdecrement operators ++ and --
perform the operations after yielding the former value, the
implication of "after" is often misunderstood. It is _not_
guaranteed that the operation is performed immediately after
giving up the previous value and before any other part of the
expression is evaluated. It is merely guaranteed that the
update will be performed sometime before the expression is
considered "finished" (before the next "sequence point," in ANSI
C's terminology). In the example, the compiler chose to
multiply the previous value by itself and to perform both
increments afterwards.

The behavior of code which contains multiple, ambiguous side
effects has always been undefined (see question 5.23). Don't
even try to find out how your compiler implements such things
(contrary to the ill-advised exercises in many C textbooks); as
K&R wisely point out, "if you don't know _how_ they are done on
various machines, that innocence may help to protect you."

References: K&R I Sec. 2.12 p. 50; K&R II Sec. 2.12 p. 54; ANSI
Sec. 3.3 p. 39; CT&P Sec. 3.7 p. 47; PCS Sec. 9.5 pp. 120-1.
(Ignore H&S Sec. 7.12 pp. 190-1, which is obsolete.)

4.3: I've experimented with the code

int i = 2;
i = i++;

on several compilers. Some gave i the value 2, some gave 3, but
one gave 4. I know the behavior is undefined, but how could it
give 4?

A: Undefined behavior means _anything_ can happen. See question
5.23.

Dan
--
Dan Pop
CERN, CN Division
Email: dan...@cernapo.cern.ch
Mail: CERN - PPE, Bat. 31 R-004, CH-1211 Geneve 23, Switzerland

Tanmoy Bhattacharya

unread,
Feb 10, 1995, 11:12:39 AM2/10/95
to
In article <D3r2x...@LinkAge.com>, har...@linkage.com writes:
<snip>

|> How i = i++ gets evaluated is implimentation defined. Compiler A is free to

I am loath to carry on this thread further (more than one, i = i++ does not
deserve!) However, I must point out that `implementation defined' is different
from `undefined' and i = i++ is undefined.

There are actually three related terms.

`unspecified' chooses one out of many behaviours, any of which can happen. No
behaviour outside this set is permitted; and unspecified behaviour is not an
error in general. The implementation need not choose the same behaviour in every
program that you write or in every statement of the same code even. (For example,
the order of elements in an array sorted by qsort, when the comparison function
treats them as equal.)

`implementation defined' behaviour means the implementation must choose some
behaviour and document it. In every program and every statement that uses this
feature, it must follow this documented behaviour. (For example `sizeof(int)')

`undefined' means that the compilers behaviour is completely unspecified. Any
action is permissible. It is always an error. (For example `i = i++')

(Was the difference between unspecified and undefined clear? The former only
allows a choice between a few different behaviours. Undefined allows the
implementation to do abslolutely _anything_. Programs using unspecified and
implementation behaviour can still be called C. Programs using undefined
behaviour are always erroneous as C programs.)

Ed Henderson

unread,
Feb 13, 1995, 5:14:56 PM2/13/95
to
j...@and.nl (Jos Horsmeier) writes:

>In article <D3rFD...@nyongwa.montreal.qc.ca> mat...@nyongwa.montreal.qc.ca (Albert Yale) writes:
>|David C. M. Bilsby (bil...@signal.dra.hmg.gb) wrote:
>|

>|: i = i++;
>|:


>|: What is the correct asnwer returned, is it 2 or 3 ?

>|i say 3.
>|
>|i = i so i = 2 then i is incremented to 3. simple. why? cuz ++ is a postfix
>|so evaluated last.

>I'd say 42, and in the mean time, the machine turns your mother into
>a hamster and it makes your father smell like elderberries. And the
>machine would say `beeb'. Or maybe not, 'cause it's all caused by:

> U N D E F I N E D B E H A V I O R

>case closed ...

>kind regards,

>Jos aka j...@and.nl

Hmm. Lets think here.
int i = 1;

i = i;
// seems fair, just useless. i ends up with no net change.

i++;
// familiar construction no? i incremented by 1.
i = i++;
// a combination of the previous two constructions. The first
// construction, i=i, again, does nothing. Only after the i=i
// is evaluated, i++ is evaluated. The result, i is incremented
// by one. Not undefined behaviour at all.

BTW, I verified this behaviour on 2 compilers. Can you say the same?

--
These opinions are mine, and do not represent those of SSi or TDK.
Edward Henderson | .. I am come that they might have life,
ed.hen...@tus.ssi1.com | and that they may have it more abundantly.
| John 10:10b

Arjan Kenter

unread,
Feb 15, 1995, 8:47:49 AM2/15/95
to
In article <tedh.792713696@delab4>, te...@delab4.tus.ssi1.com (Ed Henderson) writes:
> j...@and.nl (Jos Horsmeier) writes:
> >In article <D3rFD...@nyongwa.montreal.qc.ca> mat...@nyongwa.montreal.qc.ca (Albert Yale) writes:
> >|David C. M. Bilsby (bil...@signal.dra.hmg.gb) wrote:
> >|
> >|: i = i++;
> >|:
> >|: What is the correct asnwer returned, is it 2 or 3 ?
[...]

> >I'd say 42, and in the mean time, the machine turns your mother into
> >a hamster and it makes your father smell like elderberries. And the
> >machine would say `beeb'. Or maybe not, 'cause it's all caused by:
>
> > U N D E F I N E D B E H A V I O R
>
> >case closed ...

And so would I say, but...

> Hmm. Lets think here.

...some people think they're cleverer (sigh).

> int i = 1;
>
> i = i;
> // seems fair, just useless. i ends up with no net change.
>
> i++;
> // familiar construction no? i incremented by 1.

So far, so good...

> i = i++;

...but not this.

[ bogus explanation deleted ]

> BTW, I verified this behaviour on 2 compilers. Can you say the same?

I have verified the faq and have read comp.lang.c for a year and a half
and have read the discussions about this topic by a number of knowledgeable
people before pretending I know what it is about. (I do pretend so now :-)


Can you say the same?

One last word: verifying something on one or more compilers can only tell
you if something is *not* correct. If something compiles and gives the same
result on different compilers, then all you know is the piece of code is
probably *syntactically* correct. Nothing more. The ISO C Standard is what
you should consult to find out if something is alright or not. Lacking that,
all you can rely on is the discussion by language lawyers and the faq, which
contains the outcomes of several such discussions.

If you need the faq (I'd say you do), download it from rtfm.mit.edu from the
directory /pub/usenet/comp.lang.c, or get it from the newsgroups news.answers
or comp.answers. If you have the patience you can also just wait for it, it
is posted to this group every month.

--
^^
ir. H.J.H.N. Kenter oo ) ken...@cs.utwente.nl
University of Twente =x= \ tel. +31 53 894099
Tele-Informatics & Open Systems | \ tfx. +31 53 333815
P.O. Box 217 7500 AE Enschede /|__ \
The Netherlands (____)_/

Famous last words: Segmentation Fault (core dumped)

John Sullivan

unread,
Feb 16, 1995, 6:58:35 AM2/16/95
to
In article <tedh.792713696@delab4> te...@delab4.tus.ssi1.com (Ed Henderson) writes:

>>|: i = i++;
>>|: What is the correct asnwer returned, is it 2 or 3 ?

>>I'd say 42, and in the mean time, the machine turns your mother into


>>a hamster and it makes your father smell like elderberries. And the
>>machine would say `beeb'. Or maybe not, 'cause it's all caused by:
>> U N D E F I N E D B E H A V I O R
>>case closed ...
>>kind regards,
>>Jos aka j...@and.nl

> Hmm. Lets think here.

You don't even have to do that. Read the FAQ.

> int i = 1;
> i = i;
>// seems fair, just useless. i ends up with no net change.
> i++;
> // familiar construction no? i incremented by 1.
> i = i++;
> // a combination of the previous two constructions. The first
> // construction, i=i, again, does nothing. Only after the i=i
> // is evaluated, i++ is evaluated. The result, i is incremented
> // by one. Not undefined behaviour at all.

This is crazy. And wrong. It's undefined. It's defined as undefined. You
can tweeze the logic any way you want, but it's undefined.

> BTW, I verified this behaviour on 2 compilers. Can you say the same?

This is not proof. The compiler can do anything it wants with i=i++. A third
could give you 42.

>These opinions are mine, and do not represent those of SSi or TDK.

Or anybody else, I hope.

>Edward Henderson | .. I am come that they might have life,
>ed.hen...@tus.ssi1.com | and that they may have it more abundantly.
> | John 10:10b

(Sorry to keep this incredibly stupid thread alive, but some beginners rely on
this group for advice, which is seeming less and less like a good idea...)

Arne Vajhoej

unread,
Feb 16, 1995, 1:06:33 PM2/16/95
to
In article <tedh.792713696@delab4>, te...@delab4.tus.ssi1.com (Ed Henderson) writes:
> i = i++;
> // a combination of the previous two constructions. The first
> // construction, i=i, again, does nothing. Only after the i=i
> // is evaluated, i++ is evaluated. The result, i is incremented
> // by one. Not undefined behaviour at all.
> BTW, I verified this behaviour on 2 compilers. Can you say the same?

How do you conclude that something is not undefined
behaviour by testing on TWO compilers ?

I mean consider the 50%-50% case, then there will still be 50% chance
of identical results and 25% chance of a specfic result !

If one were to very strict, then you could test it on every C compiler in the
world and get the same result and still has proved nothing, because what
counts is the ANSI C standard.

(Well - I believe in de facto standards evolving for compilers, so I would
not go so far, but a lot of people would !)

Arne

Arne Vajhøj local DECNET: KO::ARNE
Computer Department PSI: PSI%238310013040::ARNE
Southern Denmark Business School Internet: AR...@KO.HHS.DK
WWW URL: http://www.hhs.dk/~arne/arne.html

Scott Peimann

unread,
Feb 17, 1995, 1:21:33 PM2/17/95
to
JSUL...@fhcrc.org (John Sullivan) writes:

>> Hmm. Lets think here.


precedence order folks. there is a strictly defined precedence order.

++ before assignment.

the result is 2

i = 2;
i = i++;

is the same as saying

i = 2;
i = (i++);

if your compiler delivers different, then it is buggy.

Best Regards,
Scott Meyer Peimann

Dan Pop

unread,
Feb 17, 1995, 7:11:27 AM2/17/95
to
In <JSULLIVA.1...@fhcrc.org> JSUL...@fhcrc.org (John Sullivan) writes:

>In article <tedh.792713696@delab4> te...@delab4.tus.ssi1.com (Ed Henderson) writes:
>
>> BTW, I verified this behaviour on 2 compilers. Can you say the same?
>
>This is not proof. The compiler can do anything it wants with i=i++. A third
>could give you 42.
>

Which, BTW, is the only desirable answer for this kind of expressions :-)
I still hope that someday, someone will implement it in gcc.

Chris Torek

unread,
Feb 18, 1995, 10:34:22 AM2/18/95
to
(I have tied two separate threads together here.)

In article <dpmikese.1...@ingr.com> dpmi...@ingr.com
(David P. Mikesell) writes:
>Relational operators (<, <=, >, <=) have higher precedence than
>binary logical operators (||, &&), so the "<" is evaluated first.

In article <peimann....@minnow.sb.grci.com> Scott Peimann


<pei...@minnow.sb.grci.com> writes:
>there is a strictly defined precedence order. ++ before assignment.

>[For `i = 2; i = i++;'] the result is 2 ...

Both of these articles make the same basic mistake: they equate
*parse* order with *evaluation* order.

While there is some connection---for instance, it is impossible to
evaluate an expression without first parsing it---these two steps
are essentially independent. `Operator precedence' ONLY affects
parsing. Like associativity, the concept of precedence is used
only to choose one of several possible parses. Given:

result = a - b + c * d - e;

we must choose some grouping for the various operations. We could
use strict left-to-right grouping and treat this as:

((((a - b) + c) * d) - e)

but this would upset people who expect the multiply to occur first.
The same problem would occur if we used strict right-to-left grouping.
In modern languages, one easy way to get the desired grouping is to
use an operator-precedence grammar to parse the expression. In such a
grammar, each operator is assigned a precedence---hence the name---and
operators with higher precedence group more tightly than those with
lower precedence.

The C Standard, however, uses a different technique. It has a
fully factored grammar, in which the parser never has to choose
between two different groupings, because only one grouping is
accepted by the grammar. Thus, strictly speaking, C does not *have*
precedence. Of course, individual compilers are free to implement
parsing via precedence grammars, as long as the result is correct.

Now, once more, remember that all of this is simply in order to obtain
the correct *parse* while compiling. We want:

i = f() + g();

to mean:

i = (f() + g());

and not:

(i = f()) + g();

Once we have done that, however, there is still the question of
*evaluation* order at run-time.

Except at sequence points, the C Standard leaves the order of
evaluation unspecified.

A compiler can call f() first, then g(), or it can call g() first,
then f(). Note that when we have:

i = (f() + g());

in the source, there is hardly any question of `operator precedence'
(there are no ambiguous sentences, even in an operator-precedence parser),
but we still have questions of order of evaluation, since f() and g()
might have side effects (such as `printf("in function f()\n")').

A separate rule in the Standard requires that no single object have
more than one side effect applied to it between any two sequence points.
Since both `assignment' and `increment' are side effects, this has the
effect of rendering `i = i++' undefined. This is independent of the
fact that the order of *evaluation* of the assignment and the increment
is unspecified; in turn, the unspecified evaluation order is independent
of the fact that the grouping during parsing is well-defined.

Thus, whenever you go to analyze some C code, you must first parse
it to see what it says. During this step, you can refer to precedence
tables to see whether to multiply before adding, or follow the `->'
operator before a `++'. Once you have a valid parse, you must then
decide, separately, whether the semantics are well-defined; this
includes examining the types and values in the expression, whether
there are side effects, when they might take place, and so on. If
all of that is valid, only then can you say what the statement must
do.

Remember:

>>> Precedence and associativity are only for parsing. <<<

Do not equate `higher precedence' with `done first at runtime.'


>>> Evaluation order is effectively unspecified. <<<

Make sure your code does not depend on the actual order of evaluation.


>>> Side effects `finish' at sequence points. <<<

Loosely speaking, this means: `At a semicolon, or after the left
half of an && or || operator, or after the control expression of
a loop, or after the ? part of a ?: expression, variables take on
their assigned values.'


>>> Multiple side effects between two sequence points can
result in undefined behavior. <<<

Be careful not to use several side effects on a single variable.
Operations such as `i = i++' are right out. Operations such as
`++*p++' are technically OK, but are confusing and are generally
best avoided. Given a choice between `clever' and `clear', go for
`clear'.
--
In-Real-Life: Chris Torek, Berkeley Software Design Inc
Berkeley, CA Domain: to...@bsdi.com +1 510 549 1145

John Bickers

unread,
Feb 19, 1995, 6:08:46 AM2/19/95
to
Quoted from <3ht0m5$a...@utrhcs.cs.utwente.nl> by ken...@cs.utwente.nl (Arjan Kenter):

> One last word: verifying something on one or more compilers can only tell
> you if something is *not* correct. If something compiles and gives the same

In addition, there is no excuse for "i = i++;". It isn't an even
remotely useful construct.

> ir. H.J.H.N. Kenter oo ) ken...@cs.utwente.nl

--
*** Count Templar, ELITE (FM-287) jbic...@templar.actrix.gen.nz ***
*** "Radioactivity - It's in the air, for you and for me" - Kraftwerk ***

Lawrence Kirby

unread,
Feb 20, 1995, 4:12:07 PM2/20/95
to
In article <peimann....@minnow.sb.grci.com>
pei...@minnow.sb.grci.com "Scott Peimann" writes:

>precedence order folks. there is a strictly defined precedence order.

Precedence control operator/operand grouping in an expression, it affects
order of evaluation only to a limited extent (some might argue not at all).

not control order of evaluation, beyond a

>
> ++ before assignment.
>
>the result is 2

As has been stated repeatedly and emphatically in this thread with clear
quotations from the ANSI/ISO standard the result is undefined. Anything
can happen. The expression might run and result in i having a value of 1,2,
-453, 42, The program may seg fault, or crash in any other unspecified way.

>
> i = 2;
> i = i++;
>
>is the same as saying
>
> i = 2;
> i = (i++);

That is precisely true - both have undefined behaviour.

>if your compiler delivers different, then it is buggy.

That is not. There is no reason even the same object code should produce
the same undefined behaviour symptoms on different runs. You have a
misconception here about side effects that you need to squash.

The operators ++, -- (prefix and postfix), = += -= &= >>= etc. have 2
intrinsic effects:

1. they produce a result which is a value that can be used
as an operand by other operators (and by certain statements)

2. they cause a side effect i.e. they modify an object.

These 2 effects act and are best considered entirely independently. So
consider the following table where x0 means the original value of x i.e. before
the application of the side effect.

result side effect

x++ x0 The value x0+1 is stored in x


++x x0+1 The value x0+1 is stored in x

x=1 1 The value 1 is stored in x

x+=1 x0+1 The value x0+1 is stored in x.


Note that I have not specified any ordering for these 2 effects
because the side effect operators do not define any ordering. Also note that
I have defined the effects in such a way that ordering doesn't affect the
outcome.

As noted above operator precedence controls operator/operand grouping i.e. how
operands and results in a complex expression are linked e.g. in

a + b * c

the result of b * c is an operand to +. You may consider this to impose a
partial order of evaluation i.e. a + b must be evaluated before the
multiplication (however this isn't strictly true since the compiler might
use a totally different method to evaluate the expression which is fine if
it gives the right result). Parentheses permit the grouping to be changed e.g.

(a + b) * c

has different semantics with the result of a + b being an operand to *.

a + (b * c) is semantically absolutely completely and totally identical to
a + b * c. (in case you were in any doubt! :-) )

a + (b++ * c) is similarly identical to a + (b++ * c)

So where do side effects fit into this scheme of things? In essence they don't.
Side effects are not governed by the precedence rules in an expression
(nor are parentheses) and may occur at *any* time in that expression subject to
their own set of rules based on the concept of sequence points. so in

a + (b++ * c)

b may be incremented (or should I say set to b0+1) at any point at all between
the start and end of the expression. Following the table the result of
(b++ * c) must be b0 * c i.e. as if it was taken from the original value of b.
However there are many ways for a compiler to contrive to do this, such as
temp variables or even adjusting back from the incremented value.

There are occasions where different orderings can lead to different
results. The standard contrives to give these undefined behaviour,
i = i++ being a classic example. There are some areas where it may or may
not have been successful but these are more the subject for heated
discussion in comp.std.c.

you appeared to be saying that in the expression

/* i set to 2 */
i = (i++);

the precedence/order of evaluation (or whatever) forced the ++ side effect
to occur before the assignment and hence was lost. While thigh might be
a reasonable definition for a language it is not the case in C and I hope
this article helps to show that. Real, conforming, compilers do produce
results other than 2 for this expression.

To complete this I should really include the rules concerning side effects
and sequence points but it is getting late! However I must echo calls
in this thread to read the FAQ - nearly all of section 4 is relevant.

--
-----------------------------------------
Lawrence Kirby | fr...@genesis.demon.co.uk
Wilts, England | 7073...@compuserve.com
-----------------------------------------

Greg Limes

unread,
Feb 20, 1995, 8:02:24 PM2/20/95
to
In article <3hcmdn$k...@signal.dra.hmg.gb> bil...@signal.dra.hmg.gb (David C. M. Bilsby) writes:

| Someone posed me this question recently, what is the answer of the below
| segment of C code :
|
| int main(void)
| {
| int i = 2;
|
| i = i++;
| return(i);
| }

| What is the correct asnwer returned, is it 2 or 3 ?

Maybe.
--
-- Greg Limes li...@3do.com, li...@netcom.com
"Your reality check is in the E-mail"
Not speaking for my employer, of course
PGP key available on request

stephen

unread,
Feb 21, 1995, 6:52:04 PM2/21/95
to
Albert Yale (mat...@nyongwa.montreal.qc.ca) wrote:
: David C. M. Bilsby (bil...@signal.dra.hmg.gb) wrote:
: : i = i++;

: : What is the correct asnwer returned, is it 2 or 3 ?
Undefined. Prehaps you should read the faq.
--

####################################################
# sp...@york.ac.uk # http://www.york.ac.uk/~sp106 #
# Each set includes a turntable, nine inch icing #
# bag, six high definition nozzles... #
####################################################


Ugo Cei

unread,
Feb 26, 1995, 1:49:59 PM2/26/95
to
pei...@minnow.sb.grci.com (Scott Peimann) writes:

>precedence order folks. there is a strictly defined precedence order.

This has nothing to do with precedence. It has to do with *evaluation*
order. And it is undefined. Read the FAQ. Period.


--
Signature under construction
Ugo Cei - u...@oliver.sublink.org

stephen

unread,
Feb 27, 1995, 7:12:00 PM2/27/95
to
Scott Peimann (pei...@minnow.sb.grci.com) wrote:
: i = 2;

: i = i++;
: is the same as saying
: i = 2;
: i = (i++);
: if your compiler delivers different, then it is buggy.

Congratulations in placing the superfluous parentheses correctly.
However the result is the same, undefined behaviour. Your compiler may
deliver anything it likes.

Dan Pop

unread,
Mar 7, 1995, 4:26:29 AM3/7/95
to
In <3jh285$r...@news.iesd.auc.dk> ocw...@kom.auc.dk (ole christian wolf) writes:

>In article <3itpog$6...@castle.york.ac.uk>, sp...@york.ac.uk ("stephen") writes:
>> Scott Peimann (pei...@minnow.sb.grci.com) wrote:
>> : i = 2;
>> : i = i++;
>> : is the same as saying
>> : i = 2;
>> : i = (i++);
>> : if your compiler delivers different, then it is buggy.
>>
>> Congratulations in placing the superfluous parentheses correctly.
>> However the result is the same, undefined behaviour. Your compiler may
>> deliver anything it likes.
>
>

>It shouldn't display an undefined behaviour. According to what I know about
>C, the right hand side is evaluated first, then copied to the lvalue. In this
>case, i++ is evaluated first, giving the RHS the value 3 which is then copied
>to lvalue. i should now have the value 3.

And you should now read the c.l.c FAQ.

ole christian wolf

unread,
Mar 7, 1995, 2:33:25 AM3/7/95
to
In article <3itpog$6...@castle.york.ac.uk>, sp...@york.ac.uk ("stephen") writes:
> Scott Peimann (pei...@minnow.sb.grci.com) wrote:
> : i = 2;
> : i = i++;
> : is the same as saying
> : i = 2;
> : i = (i++);
> : if your compiler delivers different, then it is buggy.
>
> Congratulations in placing the superfluous parentheses correctly.
> However the result is the same, undefined behaviour. Your compiler may
> deliver anything it likes.

It shouldn't display an undefined behaviour. According to what I know about
C, the right hand side is evaluated first, then copied to the lvalue. In this
case, i++ is evaluated first, giving the RHS the value 3 which is then copied
to lvalue. i should now have the value 3.


--

****************************************************************
* Ole Wolf Phone: +45 9817 7861 *
* Lindholmsvej 12 A Email: ocw...@kom.auc.dk *
* 9400 Nørresundby Group: S820, B1-213 *
* Denmark *
****************************************************************
* The Wolfian satanic paradox: It is good to be evil. *
****************************************************************


dma...@freenet.edmonton.ab.ca

unread,
Mar 9, 1995, 1:55:35 PM3/9/95
to
Mike Rubenstein Phoenix Contract (rubenst%occs.nlm.nih.gov) wrote:
: ole christian wolf (ocw...@kom.auc.dk) wrote:
...

: > It shouldn't display an undefined behaviour. According to what I know about


: > C, the right hand side is evaluated first, then copied to the lvalue. In this
: > case, i++ is evaluated first, giving the RHS the value 3 which is then copied
: > to lvalue. i should now have the value 3.

: Unfortunately, what you know about see is wrong. This is discussed in the
: FAQ. The standard is very clear -- this results in undefined behavior; see
: ISO 6.3.

I think part of this reason this discussion is repeated ad infinitum is
because the FAQ essentially says "don't do that!" without saying why it
doesn't make sense. I now fully accept that n=n++ is ambiguous but only
because I proved to my own satisfaction that reasonable interpretations
could lead to n either being unchanged or being incremented once the
statement is finished. Perhaps the FAQ should be amended to say WHY the
standard says this is undefined behaviour, phrased to make it clear to the
novice? Otherwise the fact that people may be lucky enough to get what they
expected will lead them to believe that the rule is simply arbitrary.

The following is off the top of my head; I'm sure it could be phrased
better;

Given
n=2; n=(n++); printf("%d\n",n);
what will be printed? (Yes, I know the brackets are redundant - they're
to emphasize the irrelevance of precedence to this issue).

Possibility 1
n is assigned the old value of n (2). n is then incremented. 3 is printed.
Possibility 2
The old value of n (2) is put in temporary storage (maybe a register). n
is incremented. The OLD value of n that we put in temp. storage (2) is then
assigned to n. 2 is printed.

Both possibilities are valid interpretations of post-increment. Since n=n++
can be interpreted in at least two ways it can THEN be reasonably argued
that its behaviour is undefined.

--
---
Douglas Martin email: dma...@freenet.edmonton.ab.ca
#510 8210 111 St. phone: 439-1939
Edmonton, AB, T6G 2C7

Dan Pop

unread,
Mar 9, 1995, 2:13:21 PM3/9/95
to

>Mike Rubenstein Phoenix Contract (rubenst%occs.nlm.nih.gov) wrote:
>: ole christian wolf (ocw...@kom.auc.dk) wrote:
>...
>
>: > It shouldn't display an undefined behaviour. According to what I know about
>: > C, the right hand side is evaluated first, then copied to the lvalue. In this
>: > case, i++ is evaluated first, giving the RHS the value 3 which is then copied
>: > to lvalue. i should now have the value 3.
>
>: Unfortunately, what you know about see is wrong. This is discussed in the
>: FAQ. The standard is very clear -- this results in undefined behavior; see
>: ISO 6.3.
>
>I think part of this reason this discussion is repeated ad infinitum is
>because the FAQ essentially says "don't do that!" without saying why it
>doesn't make sense. I now fully accept that n=n++ is ambiguous but only

It doesn't make sense because it isn't defined. n=n++ isn't ambiguous,
it's undefined. If the standard said "all side effects are completed
before the assignment is performed" it would have been perfectly well
defined. If the standard wanted n=n++ to be ambiguous, it would have
made it "implementation defined", not "undefined".

>because I proved to my own satisfaction that reasonable interpretations
>could lead to n either being unchanged or being incremented once the
>statement is finished. Perhaps the FAQ should be amended to say WHY the
>standard says this is undefined behaviour, phrased to make it clear to the
>novice? Otherwise the fact that people may be lucky enough to get what they
>expected will lead them to believe that the rule is simply arbitrary.
>
>The following is off the top of my head; I'm sure it could be phrased
>better;
>
>Given
> n=2; n=(n++); printf("%d\n",n);
>what will be printed? (Yes, I know the brackets are redundant - they're
>to emphasize the irrelevance of precedence to this issue).
>
>Possibility 1
>n is assigned the old value of n (2). n is then incremented. 3 is printed.
>Possibility 2
>The old value of n (2) is put in temporary storage (maybe a register). n
>is incremented. The OLD value of n that we put in temp. storage (2) is then
>assigned to n. 2 is printed.
>
>Both possibilities are valid interpretations of post-increment. Since n=n++
>can be interpreted in at least two ways it can THEN be reasonably argued
>that its behaviour is undefined.

You've got it wrong. The behaviour is undefined because the standard
makes it so. It's that simple. The standard could have defined
it (it didn't mainly for performance of implementation reasons) and then
the behaviour would have been perfectly well defined.

Darin McBride

unread,
Mar 9, 1995, 4:12:58 PM3/9/95
to
ocw...@kom.auc.dk (ole christian wolf) writes:

> In article <3itpog$6...@castle.york.ac.uk>, sp...@york.ac.uk ("stephen") write

> > Scott Peimann (pei...@minnow.sb.grci.com) wrote:
> > : i = 2;
> > : i = i++;
> > : is the same as saying
> > : i = 2;
> > : i = (i++);
> > : if your compiler delivers different, then it is buggy.
> >
> > Congratulations in placing the superfluous parentheses correctly.
> > However the result is the same, undefined behaviour. Your compiler may
> > deliver anything it likes.
>
>
> It shouldn't display an undefined behaviour. According to what I know about
> C, the right hand side is evaluated first, then copied to the lvalue. In this
> case, i++ is evaluated first, giving the RHS the value 3 which is then copied
> to lvalue. i should now have the value 3.

No, the RHS value is 2. The question is whether the post-increment
operator applies before or after the assignment operator. And if the
parenthesis are applies as above, does that change when the
post-increment operator is applied?


--
Darin McBride - mcb...@tower.ve6mgs.ampr.ab.ca
Sig reduced by 25% to do my part in reducing the deficit of electrons.

Keeper: alt.bbs.renegade FAQ
Soon to keep: ab.kodish.idiocies FAQ

Mike Rubenstein Phoenix Contract

unread,
Mar 8, 1995, 10:52:00 PM3/8/95
to
ole christian wolf (ocw...@kom.auc.dk) wrote:
> In article <3itpog$6...@castle.york.ac.uk>, sp...@york.ac.uk ("stephen") writes:
> > Scott Peimann (pei...@minnow.sb.grci.com) wrote:
> > : i = 2;
> > : i = i++;
> > : is the same as saying
> > : i = 2;
> > : i = (i++);
> > : if your compiler delivers different, then it is buggy.
> >
> > Congratulations in placing the superfluous parentheses correctly.
> > However the result is the same, undefined behaviour. Your compiler may
> > deliver anything it likes.


> It shouldn't display an undefined behaviour. According to what I know about
> C, the right hand side is evaluated first, then copied to the lvalue. In this
> case, i++ is evaluated first, giving the RHS the value 3 which is then copied
> to lvalue. i should now have the value 3.

Unfortunately, what you know about see is wrong. This is discussed in the


FAQ. The standard is very clear -- this results in undefined behavior; see
ISO 6.3.

--
Mike Rubenstein

joshua

unread,
Mar 9, 1995, 1:52:31 AM3/9/95
to
ole christian wolf (ocw...@kom.auc.dk) wrote:


: --

No, sorry, the other guy knows C much better then you. It IS
definitly undefined behavior. Try to resist the urge to reply
unless you are sure as to what your talking about. I know from
experience that it can be hard, but not impossible!

-- Joshua

Dan Pop

unread,
Mar 10, 1995, 7:11:37 AM3/10/95
to

>ocw...@kom.auc.dk (ole christian wolf) writes:
>
>> In article <3itpog$6...@castle.york.ac.uk>, sp...@york.ac.uk ("stephen") write
>> > Scott Peimann (pei...@minnow.sb.grci.com) wrote:
>> > : i = 2;
>> > : i = i++;
>> > : is the same as saying
>> > : i = 2;
>> > : i = (i++);
>> > : if your compiler delivers different, then it is buggy.
>> >
>> > Congratulations in placing the superfluous parentheses correctly.
>> > However the result is the same, undefined behaviour. Your compiler may
>> > deliver anything it likes.
>>
>>
>> It shouldn't display an undefined behaviour. According to what I know about
>> C, the right hand side is evaluated first, then copied to the lvalue. In this
>> case, i++ is evaluated first, giving the RHS the value 3 which is then copied
>> to lvalue. i should now have the value 3.
>
>No, the RHS value is 2. The question is whether the post-increment
>operator applies before or after the assignment operator. And if the

It's even worse. On a parallel machine, they could occur simultaneously,
because the compiler knows that i can be modified only once, so it doesn't
attempt to handle this possibility. The question about the order in
which the operations occur is really moot, because it's not this order
which is undefined (this would have meant "unspecified behavior"), but
the behaviour of the entire program, which could legally crash when i = i++
is executed.

Dan Pop

unread,
Mar 9, 1995, 4:35:12 PM3/9/95
to
In <danpop.794776401@rscernix> dan...@cernapo.cern.ch I wrote:

>In <3jniv7$b...@news.sas.ab.ca> dma...@freenet.edmonton.ab.ca () writes:
>>
>>I think part of this reason this discussion is repeated ad infinitum is
>>because the FAQ essentially says "don't do that!" without saying why it
>>doesn't make sense. I now fully accept that n=n++ is ambiguous but only
>
>It doesn't make sense because it isn't defined. n=n++ isn't ambiguous,
>it's undefined. If the standard said "all side effects are completed
>before the assignment is performed" it would have been perfectly well
>defined. If the standard wanted n=n++ to be ambiguous, it would have
>made it "implementation defined", not "undefined".

^^^^^^^^^^^^^^^^^^^^^^
One second after posting it, I realized that I wrote "implementation
defined", when I was actually meaning "unspecified". For reference,
here are the definitions of these terms:

* Unspecified behavior --- behavior, for a correct program construct
and correct data, for which the Standard imposes no requirements.

* Undefined behavior --- behavior, upon use of a nonportable or
erroneous program construct, of erroneous data, or of
indeterminately-valued objects, for which the Standard imposes no
requirements. Permissible undefined behavior ranges from ignoring the
situation completely with unpredictable results, to behaving during
translation or program execution in a documented manner characteristic
of the environment (with or without the issuance of a diagnostic
message), to terminating a translation or execution (with the issuance
of a diagnostic message).

* Implementation-defined behavior --- behavior, for a correct program
construct and correct data, that depends on the characteristics of the
implementation and that each implementation shall document.

dma...@freenet.edmonton.ab.ca

unread,
Mar 10, 1995, 12:19:19 PM3/10/95
to
Dan Pop (dan...@cernapo.cern.ch) wrote:

: * Undefined behavior --- behavior, upon use of a nonportable or


: erroneous program construct, of erroneous data, or of
: indeterminately-valued objects, for which the Standard imposes no

^^^^^^^^^^^^^^^^^^^^^^

Thank you! I like that even better than "ambiguous" and it's IN THE
STANDARD!!

You're missing my point. n=n++ is undefined for a reason, and that reason
is not simply the fact that the standard says so. The standard writers had
very good reasons for deciding that n=n++ and friends are undefined. Those
reasons are not that difficult to state, nor is an illustration of the
problem difficult to provide, BY SOMEONE THAT UNDERSTANDS the problem, which
I did not at first, and quite obviously a great many people still don't.

You can say "THE STANDARD SAYS IT'S UNDEFINED BEHAVIOUR!!!" until your
keyboard wears out and you still won't have answered the basic question of
WHY?

If people know the answer to that basic question they are
a) less likely to try to argue the validity of n=n++
and
b) less likely to decide the standard is full of s--t and ignore it, because
"n=n++; works 'properly' on my machine - what's the problem?"

Greg Black

unread,
Mar 10, 1995, 2:57:40 AM3/10/95
to
dma...@freenet.edmonton.ab.ca () writes:

>I think part of this reason this discussion is repeated ad infinitum is
>because the FAQ essentially says "don't do that!" without saying why it
>doesn't make sense.

[Confused thinking deleted.]

The FAQ does say why, but many people seem not to understand it,
perhaps because it only says it once. Here's a more detailed answer,
taken from the Standard in Section 6.3:

Between the previous and next sequence point an object shall have
its stored value modified at most once by the evaluation of an
expression. Furthermore, the prior value shall be accessed only
to determine the value to be stored.

It then has a footnote (not part of the Standard, but interesting all
the same) that specifically states:

This paragraph renders undefined statement expressions such as

i = ++i + 1;

All these expressions that are discussed so often attempt to modify
the stored value more than once, and so lead to undefined results.
Any result can be given, and it doesn't matter at all if the result
appears to `make sense' or not -- it is undefined.

--
Greg Black -- g...@gba.oz.au

C.W.Racer

unread,
Mar 10, 1995, 6:00:43 PM3/10/95
to
In article <danpop.794862450@rscernix>, dan...@cernapo.cern.ch (Dan Pop) writes:

|> In <3jq1mn$6...@news.sas.ab.ca> dma...@freenet.edmonton.ab.ca () writes:
|>
|> >Dan Pop (dan...@cernapo.cern.ch) wrote:
|> >
|> >: * Undefined behavior --- behavior, upon use of a nonportable or
|> >: erroneous program construct, of erroneous data, or of
|> >: indeterminately-valued objects, for which the Standard imposes no
|> > ^^^^^^^^^^^^^^^^^^^^^^
|> >
|> >Thank you! I like that even better than "ambiguous" and it's IN THE
|> >STANDARD!!
|>
|> You are missing point after point. "indeterminately-valued objects"
|> above refers to situations like this one:
|>
|> main()
|> {
|> int i, j;
|>
|> j = i; /* undefined behaviour, because the value of i is indeterminate */

|> }
|> >
|> >You're missing my point. n=n++ is undefined for a reason, and that reason
|> >is not simply the fact that the standard says so. The standard writers had
|>
|> You're the one missing the point. n=n++ is undefined because the standard
|> doesn't allow an object to have its value changed more than once between
|> sequence points.
|>
|> >very good reasons for deciding that n=n++ and friends are undefined. Those
|> >reasons are not that difficult to state, nor is an illustration of the
|> >problem difficult to provide, BY SOMEONE THAT UNDERSTANDS the problem, which
|> >I did not at first, and quite obviously a great many people still don't.
|> >
|> >You can say "THE STANDARD SAYS IT'S UNDEFINED BEHAVIOUR!!!" until your
|> >keyboard wears out and you still won't have answered the basic question of
|> >WHY?
|>

Maybe the question is: why write n = n++; instead of n++; ?
Does this appeal to some sense of clarity , or balance?

I think it is undefined because it has no value.
--
| Chick Racer Chevron Petroleum Technology Co. |
| (713) 596-2430 P.O. Box 42832 |
| gac...@chevron.com Houston, Tx 77242-2832 |
| 4209 Hayes Rd. |

Dan Pop

unread,
Mar 10, 1995, 2:07:30 PM3/10/95
to

>Dan Pop (dan...@cernapo.cern.ch) wrote:
>
>: * Undefined behavior --- behavior, upon use of a nonportable or
>: erroneous program construct, of erroneous data, or of
>: indeterminately-valued objects, for which the Standard imposes no
> ^^^^^^^^^^^^^^^^^^^^^^
>
>Thank you! I like that even better than "ambiguous" and it's IN THE
>STANDARD!!

You are missing point after point. "indeterminately-valued objects"


above refers to situations like this one:

main()
{
int i, j;

j = i; /* undefined behaviour, because the value of i is indeterminate */
}
>

>You're missing my point. n=n++ is undefined for a reason, and that reason
>is not simply the fact that the standard says so. The standard writers had

You're the one missing the point. n=n++ is undefined because the standard


doesn't allow an object to have its value changed more than once between
sequence points.

>very good reasons for deciding that n=n++ and friends are undefined. Those


>reasons are not that difficult to state, nor is an illustration of the
>problem difficult to provide, BY SOMEONE THAT UNDERSTANDS the problem, which
>I did not at first, and quite obviously a great many people still don't.
>
>You can say "THE STANDARD SAYS IT'S UNDEFINED BEHAVIOUR!!!" until your
>keyboard wears out and you still won't have answered the basic question of
>WHY?

I did, because this is the right answer. Your "answer" doesn't explain
why the standard chose "undefined behaviour" instead of "unspecified
behaviour" or "implementation defined behaviour". It won't convince
anybody who can think for himself. If you really need a more concrete
reason (you shouldn't), take this one: to allow high performance
implementations, especially on parallel machines, where the two changes
of n could occur _simultaneously_. If the compiler knows in advance
that no variable can be modified twice, it doesn't has to bother with
extra precautions. Hence n=n++ is _illegal_ in C.

When you'll actually read the standard, you'll see that it is written
in a strange language (called "standardese" :-) It isn't something that
can be understood (or is meant to be understood), it has to be followed
by the compiler implementors and by the programmers. It is sort of an
agreement between the implementor and the programmer: "If you, the
programmer, follow the letter of the standard, I, the implementor,
guarantee that you'll get the results you expect". If any of the parties
breaks the agreement, the result is chaos.

This is true for any standard, not only for those about programming
languages. You don't have to understand why 1 inch == 25.4 mm. Just
follow it, and your bolts will fit into nuts manufactured in another
country, on another continent.


>
>If people know the answer to that basic question they are
>a) less likely to try to argue the validity of n=n++
> and
>b) less likely to decide the standard is full of s--t and ignore it, because
> "n=n++; works 'properly' on my machine - what's the problem?"

I definitely agree with these points. We don't agree about the answer,
however :-)

Steve Summit

unread,
Mar 11, 1995, 5:04:35 PM3/11/95
to
In article <danpop.794862450@rscernix>, Dan Pop

(dan...@cernapo.cern.ch) writes:
> In <3jq1mn$6...@news.sas.ab.ca> dma...@freenet.edmonton.ab.ca () writes:
>> You can say "THE STANDARD SAYS IT'S UNDEFINED BEHAVIOUR!!!" until your
>> keyboard wears out and you still won't have answered the basic question of
>> WHY?
>
> I did, because this is the right answer. Your "answer" doesn't explain
> why the standard chose "undefined behaviour" instead of "unspecified
> behaviour" or "implementation defined behaviour". It won't convince
> anybody who can think for himself.

Actually, Douglas and Dan are both right.

Posters to comp.lang.c do assert, over and over and over again,
that certain behavior is undefined. It doesn't help. Other
posters keep asking "Why?" or saying "Oh, but if I don't care
which outcome I get, I'm okay."

Posters to comp.lang.c do assert, over and over and over again,
that "No, it's UNDEFINED! Undefined behavior means that ANYTHING
can happen! If you write i=i++, your computer can teleport
itself to 16th century Wittenberg and change Western history by
nailing sections 1.6 and 3.3 of ANSI X3.159 to the church door!".
It still doesn't help. Hyperbolic scenarios like that are fun to
construct, but if someone has heard but not accepted one sober
definition of undefined behavior, and persists in their dogged
belief that i=i++ is meaningful to them and their compiler, those
increasingly fantastic explanations don't usually penetrate,
either.

If we want to educate, if we want people to stop believing that
they can write i=i++ or predict what it should do, we can't just
keep repeating "It's undefined". We can't say anything that
sounds like "It's undefined because we and the Standard say it
is, so just accept it." If it sounds like that, if it can
possibly be construed to sound like that, then people with a
hyperactive (but perhaps beneficial, in other situations)
skepticism gland *will* construe it like that, and will cross
their arms, state that they're from Missouri, and demand that we
show them why. We can't say "because the Standard says so" for
the nth time -- they remain unconvinced. We can't emulate an
inane beer commercial and say "Why ask why?" -- their arms remain
crossed. We have to give them a reason, in language they can
understand, and if we think that the best reason really *is*
"because the Standard says so," or that it's not really sensible
to ask why or meaningful to explain why, then we had better --
again, if we're interested in educating and in keeping the noise
level down -- keep those opinions to ourselves.

I keep trying to find ways of saying these things that really
work. (Two other FAQ list issues that seem to defy being put to
rest are whether arrays are pointers, and whether it's possible
to write a generic swap macro.) You may think that the current
FAQ list wording is adequate (if so, thank you! :-) ), and that
people, having read it, shouldn't keep wondering why things are
the way they are, but FAQ lists are by their very nature
pragmatic: if people manage not to understand them, then they
(the lists) are not doing their job. If an FAQ list which merely
stated the facts were adequate, if it were a reader's fault for
misunderstanding it, then we wouldn't need FAQ lists at all;
there are already plenty of documents out there which merely
state the facts, and which readers manage to misunderstand.


Roger Miller came up with a very nice explanation of how behavior
which the pedants claim is undefined can seem to work "correctly"
on the skeptic's computer:

Somebody once told me that in basketball you can't hold
the ball and run. I got a basketball and tried it and it
worked just fine. He obviously didn't understand basketball.

(This observation can also be used to make Dan's point: about the
only answer to the question "Why can't you hold the ball and run
in basketball?" is "because it's against the rules" or "because
that's not the way the game is played.")

At one time I was toying with statements of the form

Undefined means that, notwithstanding question 8.2,
the code

printf("%d", j++ <= j);

can print 42, or "forty-two".

(For those who don't have a copy of the FAQ list in front of you,
question 8.2 is the one that says that boolean operators like <=
always return 0 or 1. I confess that by mentioning the number
42, I've started down the road towards hyperbole.) I think I
even once posted here something along the lines of

Boolean operators like <= always return 0 or 1.
The code

printf("%d", j++ <= j);

can print 42, or "forty-two".
If you can hold these two thoughts simultaneously,
you will have achieved Enlightenment.

These arguments do have a certain subtle appeal, but when you're
trying to pierce those curtains of skepticism, it seems that
neither subtlety nor hit-em-over-the-head, nasal demons arguments
are sufficient.

The massive FAQ list revision I'm currently immersed in (and
which I shouldn't even be taking time out from to post this
article) has a bunch more to say about undefined behavior;
we'll see if any of it helps.

Steve Summit
s...@eskimo.com

Magao

unread,
Mar 11, 1995, 7:22:15 PM3/11/95
to
s...@eskimo.com (Steve Summit) writes:

>If we want to educate, if we want people to stop believing that
>they can write i=i++ or predict what it should do, we can't just
>keep repeating "It's undefined". We can't say anything that
>sounds like "It's undefined because we and the Standard say it
>is, so just accept it." If it sounds like that, if it can

The best way I can think of to convince someone that something should
not be used because it is undefined is ...

1) Tell them the standard says that it is undefined and
2) Tell them that this is because ...
a) For reasons of efficiency the standard does not wish to impose
*certain* behaviours on all architectures *because*
b) To attain the maximum speed for a particular operation on a
particular platform shortcuts must be taken which then render
other operations relying on that one to *return* the *expected*
value invalid.

(I know ... a bit convoluted, but it serves so long as there are examples
to go with it).

A good example was given a few days ago for i = i++ (I forgot to save it)
showing *how* the code was optimised step by step. The value finally
returned had little relation to the "expected" value, as the result from
incrementing i was dropped was not needed as it was being assigned, etc.
(Dammit, why didn't I save that article ???)

Tim Delaney ct...@uow.edu.au
TCD Software

Fred J. McCall

unread,
Mar 13, 1995, 10:29:48 AM3/13/95
to
In article <3jq1mn$6...@news.sas.ab.ca> dma...@freenet.edmonton.ab.ca () writes:

>You're missing my point. n=n++ is undefined for a reason, and that reason
>is not simply the fact that the standard says so. The standard writers had
>very good reasons for deciding that n=n++ and friends are undefined. Those
>reasons are not that difficult to state, nor is an illustration of the
>problem difficult to provide, BY SOMEONE THAT UNDERSTANDS the problem, which
>I did not at first, and quite obviously a great many people still don't.

Note that you still haven't specified 'the problem'. They could have
standardized it to do anything they wanted it to. They elected not to. It's
got nothing to do with your prior 'explanation' about more than one
'reasonable' interpretation. They could, after all, have simply picked one.

It's undefined because the Standard says it is undefined. They could have
made it implementation defined. they didn't. They could have made it defined
behaviour. They didn't. It was explicitly made undefined behaviour, and it
is hence undefined behaviour. BECAUSE THE STANDARD SAYS IT IS.

>You can say "THE STANDARD SAYS IT'S UNDEFINED BEHAVIOUR!!!" until your
>keyboard wears out and you still won't have answered the basic question of
>WHY?

Neither have you. It is because it is.

>If people know the answer to that basic question they are
>a) less likely to try to argue the validity of n=n++
> and
>b) less likely to decide the standard is full of s--t and ignore it, because
> "n=n++; works 'properly' on my machine - what's the problem?"

And just why is that? If they'll argue with the fact that the Standard simply
says it is undefined behaviour, why is 'logic' going to sway them? This is
like insisting that one must logically explain *why* things fall before
someone will believe in the Universal Law of Gravitation. They fall because
it is one of the properties of the universe. In other words, because the
Standard says so.


Fred J. McCall

unread,
Mar 13, 1995, 10:29:53 AM3/13/95
to
In article <3jq1mn$6...@news.sas.ab.ca> dma...@freenet.edmonton.ab.ca () writes:

>You're missing my point. n=n++ is undefined for a reason, and that reason
>is not simply the fact that the standard says so. The standard writers had
>very good reasons for deciding that n=n++ and friends are undefined. Those
>reasons are not that difficult to state, nor is an illustration of the
>problem difficult to provide, BY SOMEONE THAT UNDERSTANDS the problem, which
>I did not at first, and quite obviously a great many people still don't.

Note that you still haven't specified 'the problem'. They could have

standardized it to do anything they wanted it to. They elected not to. It's
got nothing to do with your prior 'explanation' about more than one
'reasonable' interpretation. They could, after all, have simply picked one.

It's undefined because the Standard says it is undefined. They could have
made it implementation defined. they didn't. They could have made it defined
behaviour. They didn't. It was explicitly made undefined behaviour, and it
is hence undefined behaviour. BECAUSE THE STANDARD SAYS IT IS.

>You can say "THE STANDARD SAYS IT'S UNDEFINED BEHAVIOUR!!!" until your


>keyboard wears out and you still won't have answered the basic question of
>WHY?

Neither have you. It is because it is.

>If people know the answer to that basic question they are

>a) less likely to try to argue the validity of n=n++
> and
>b) less likely to decide the standard is full of s--t and ignore it, because
> "n=n++; works 'properly' on my machine - what's the problem?"

And just why is that? If they'll argue with the fact that the Standard simply

Fred J. McCall

unread,
Mar 13, 1995, 10:41:03 AM3/13/95
to
In article <3jq1mn$6...@news.sas.ab.ca> dma...@freenet.edmonton.ab.ca () writes:

>Dan Pop (dan...@cernapo.cern.ch) wrote:

>: * Undefined behavior --- behavior, upon use of a nonportable or
>: erroneous program construct, of erroneous data, or of
>: indeterminately-valued objects, for which the Standard imposes no
> ^^^^^^^^^^^^^^^^^^^^^^

>Thank you! I like that even better than "ambiguous" and it's IN THE
>STANDARD!!

>You're missing my point

No, you are missing his point. They could have simply picked one of your
'reasonable' alternatives and made it work that way. They didn't. They made
it explicitly undefined, instead. That ends the discussion.

>. n=n++ is undefined for a reason, and that reason
>is not simply the fact that the standard says so. The standard writers had
>very good reasons for deciding that n=n++ and friends are undefined. Those
>reasons are not that difficult to state, nor is an illustration of the
>problem difficult to provide, BY SOMEONE THAT UNDERSTANDS the problem, which
>I did not at first, and quite obviously a great many people still don't.

Dan has probably forgotten more C than you currently know. It is undefined
for the reason that they made it undefined. Your reasoning is like saying
that you won't believe that things fall until someone gives you a 'reason' and
that the simple fact that the Universal Law of Gravitation says they fall is
not good enough.

>You can say "THE STANDARD SAYS IT'S UNDEFINED BEHAVIOUR!!!" until your
>keyboard wears out and you still won't have answered the basic question of
>WHY?

And neither have you. The basic question of WHY is that it is. Things fall
because they do. The Standard for the universe says that they do.
Multiple side effects without an intervening sequence point are undefined.
They are undefined because they are. The Standard for the C universe says so.
Live with it.

>If people know the answer to that basic question they are
>a) less likely to try to argue the validity of n=n++
> and
>b) less likely to decide the standard is full of s--t and ignore it, because
> "n=n++; works 'properly' on my machine - what's the problem?"

So you don't believe that things fall?


dma...@freenet.edmonton.ab.ca

unread,
Mar 14, 1995, 11:51:46 AM3/14/95
to
Fred J. McCall (f...@ti.com) wrote:

: So you don't believe that things fall?

Certainly; I see regular demonstrations of that fact. And, before you
give a better example, yes I believe things like general relativity
and the uncertainty principle even though I haven't seen demonstrations; I
recognize that there are some things that CAN'T be adequately demonstrated
to a novice due to their complexity.

Let me put it this way; if you wanted to prevent your son or daughter
from smoking would you tell him/her that "the surgeon-general said 'don't do
that!'" or would you tell them why they shouldn't smoke?

My point is purely pedagogical; judging from the questions there are MANY
novices reading this newsgroup. It is trivial to demonstrate two possible
interpretations of the statement - "increment n by 1 and assign the value
that n had before incrementation to n". Once you've done that I have
absolutely no objection to saying "the standard does not define what this
statement or any other statement that alters the same variable more than
once does" (I recognize that that phrase is likely not 100% accurate in
terms of the standard; my point is that since it is trivial to do so one
should demonstrate the problem AND THEN appeal to the standard).

By the way, somebody remarked that one of the respondents (sorry - I have
a lousy memory for names) probably has a great deal more C knowledge than
I do (the reference was to forgetting more than I've ever learned). That
I fully accept, especially because it backs up MY side of the argument!
This is not an issue of whether statement x is valid, standard-conforming
C. It is an issue of helping people understand WHY statement x is or is
not valid. If he knows a great deal more C than I do, that makes it
likely that I was a novice much more recently than he was, does it not?

Fred J. McCall

unread,
Mar 15, 1995, 6:23:18 AM3/15/95
to
In article <3k4hj2$t...@news.sas.ab.ca> dma...@freenet.edmonton.ab.ca () writes:

>Fred J. McCall (f...@ti.com) wrote:

>: So you don't believe that things fall?

>Certainly; I see regular demonstrations of that fact. And, before you
>give a better example, yes I believe things like general relativity
>and the uncertainty principle even though I haven't seen demonstrations; I
>recognize that there are some things that CAN'T be adequately demonstrated
>to a novice due to their complexity.

The issue at hand has nothing to do with 'complexity'. Things fall because
it's part of the 'standard'. This is the same reason i = i++ is undefined;
because it is part of the standard.

>Let me put it this way; if you wanted to prevent your son or daughter
>from smoking would you tell him/her that "the surgeon-general said 'don't do
>that!'" or would you tell them why they shouldn't smoke?

Irrelevant.

>My point is purely pedagogical; judging from the questions there are MANY
>novices reading this newsgroup. It is trivial to demonstrate two possible
>interpretations of the statement - "increment n by 1 and assign the value
>that n had before incrementation to n". Once you've done that I have
>absolutely no objection to saying "the standard does not define what this
>statement or any other statement that alters the same variable more than
>once does" (I recognize that that phrase is likely not 100% accurate in
>terms of the standard; my point is that since it is trivial to do so one
>should demonstrate the problem AND THEN appeal to the standard).

But the point is that the Standard *could* have simply arbitrarily specified
one and said that everyone had to make it work that way. Therefore, your
'reason' is not a reason at all. The reason it is undefined is because the
Standard *says* it is undefined.

>This is not an issue of whether statement x is valid, standard-conforming
>C. It is an issue of helping people understand WHY statement x is or is
>not valid.

Not when your 'reason' is simply bogus. Statement X is valid but undefined
(for this case of X). It is valid because the language definition (the
Standard describing the syntax and grammar of the language) says it is. It
results in undefined behaviour for exactly the same reason -- the Standard
says it does.

>If he knows a great deal more C than I do, that makes it
>likely that I was a novice much more recently than he was, does it not?

That's right, and that's why you should listen to him (and to me, and to
everyone else telling you this). The REASON it is undefined is BECAUSE THE
STANDARD SAYS SO. They could have specified behaviour. They didn't. Your
'reason' is sheer sophistry. After all, I can come up with more than one
'interpretation' for how something could have been implemented for almost any
language construct. That doesn't make them all undefined.


C.W.Racer

unread,
Mar 15, 1995, 4:52:31 PM3/15/95
to
In article <3k4hj2$t...@news.sas.ab.ca>, dma...@freenet.edmonton.ab.ca () writes:
|> Fred J. McCall (f...@ti.com) wrote:
|>
********************************** stuff deleted *********************

|> interpretations of the statement - "increment n by 1 and assign the value
|> that n had before incrementation to n". Once you've done that I have
********************************** stuff deleted *********************

I may be wrong but I think this thread is about what's wrong with:

n = n++;

Namely, why isn't it defined?

I guess my question is: given the definition of n++, what would you
expect of n = n++? This is not a useful statement and is open to
ambiguity, AND should be discouraged. It is discouraged by declaring
it undefined.

Chris Torek

unread,
Mar 16, 1995, 2:20:46 AM3/16/95
to
In article <fjm.58....@ti.com> Fred J. McCall <f...@ti.com> writes:
>... The REASON it is undefined is BECAUSE THE STANDARD SAYS SO. They

>could have specified behaviour. They didn't.

Indeed, and whenever the behavior of some construct is undefined, this
is in fact the reason---the Standard defines the behavior of constructs,
and when it says one is undefined, it is.

This does, however, still leave a reasonable question. The question
is not `why is this undefined'---we now know why---but rather `why
did the members of the X3J11 committee say it was undefined?' At
this point, however, our answer must become speculative. Perhaps
they said it was undefined because they looked at it once and
everyone agreed, `Gee, that is too hard or useless to bother
defining, let's just make it undefined.' On the other hand, perhaps
they spent days arguing, in one camp or another, that it should be
defined *this* way or that it should be defined *that* way, or that
it should be defined yet *another* way. After enough hours of
arguing, perhaps someone said, `Look, guys, it has become obvious
that reasonable people could want it any number of different ways,
so let's just make it undefined.' (In some cases, the latter sort
of argument leads to: `Let's make it implementation-defined.')

Unless we hear this from someone who was actually at the meeting
at which the behavior was defined as undefined, all of this is simply
speculation.

So, once again, the correct answer for `what does i = i++' do is
`nothing useful; it is undefined', and the correct answer for `why
is it undefined' is `because the Standard says so.' The correct
answer for `why does the Standard say so' is interesting, but not
really answerable, at least not by me. (The minutes of the various
meetings may also hold such answers.)
--
Disclaimer: I have been put on Soma for a spinal muscle spasm.
This text is lower quality material than usual.
In-Real-Life: Chris Torek, Berkeley Software Design Inc
Berkeley, CA Domain: to...@bsdi.com +1 510 549 1145

Jim Frohnhofer

unread,
Mar 16, 1995, 11:50:57 AM3/16/95
to

In article 000B...@ti.com, f...@ti.com (Fred J. McCall) writes:
>That's right, and that's why you should listen to him (and to me, and to
>everyone else telling you this). The REASON it is undefined is BECAUSE THE
>STANDARD SAYS SO.

Why?

>They could have specified behaviour.

Who are they? How could they have specified behaviour. Why didn't they?

>They didn't.

Why not?

>Your
>'reason' is sheer sophistry. After all, I can come up with more than one
>'interpretation' for how something could have been implemented for almost any
>language construct. That doesn't make them all undefined.

Indeed it doesn't. So there is perhaps something that differentiates
this construct from others, that caused the 'they' from the previous
line to leave the behaviour undefined. What is that something?


I may regret this, but I'll jump in anyway. I accept that the behaviour
of such a construct is undefined simply because the Standard says so. But
isn't it legitimate for me to ask why the Standard leaves it undefined?

As far as I know, it was created by a committee not brought down by Moses
from the mountain top. If I want to become a better C programmer, won't
it help me to know why the committee acted as it did.

In the United States, the legislature has two chambers, the House of
Representatives and the Senate. I ask you why, and you tell me it's
because the Constitution says so. I ask why and you respond BECAUSE THE
CONSTITUTION SAYS SO. I again ask why and you say, irately, BECAUSE THE
CONSTITUTION SAYS SO. Does it occur to you, that perhaps what I want to
know is why the writers of the Constitution chose to do it that way?
Similarly, can't I ask why the committee did what they did?

Jim Frohnhofer

Mike Rubenstein Phoenix Contract

unread,
Mar 18, 1995, 5:53:13 PM3/18/95
to
Dan Pop (dan...@cernapo.cern.ch) wrote:
> You've got it wrong. The behaviour is undefined because the standard
> makes it so. It's that simple. The standard could have defined
> it (it didn't mainly for performance of implementation reasons) and then
> the behaviour would have been perfectly well defined.

There's an assumption that you, I, and most of those I'd consider experts
are making that does not seem to be shared by most of the novices:

C is precisely the language defined by the ISO standard.

Note, that I am not precluding talking about other languages such as Microsoft
C, Borland C, GNU C which are defined by their respective manufacturers.

My point is that a programming language is exactly what the definition of the
language says it is.

How does know that

i || ++i

is defined while

i | ++i

is not? The only way to know this is to know the rules for the
language. The definition says that there is a sequence point between the
two evaluations and specifies the order of evaluation of the former. It does
neither for the latter.

You and I might disagree as to whether it was wise to define one and not
the other, but we certainly would agree that the first is defined and
the second is not. The reason is simple -- we're reading from the same
script.

Most of the novices seem to be working without a precise definition of the
language. They try to reason out what things should mean. But this is not
possible since so many of the decisions in defining a language are arbitrary
or, at least, based on estimates of the the benefits of various constructions
that are arguable. What's wrong with void main(void)? As far as I can see
the only thing wrong with it is that the standards committee didn't think it
added enough to the language to define it. I doubt that very many of us would
be flaming about a terrible decision had it been included in the language.

How can one reason that void main(void) is not defined but int main(void) is?
I can't see any way. At least, the only way I know is is because I read it
in the standard.

Without a definition of the language, how do you explain why some things
are defined and others are not? I've no idea. With a definition, it's easy.
Things are defined if the definition of the language defines them -- that's
all.

--
Mike Rubenstein

Dan Pop

unread,
Mar 19, 1995, 10:41:58 AM3/19/95
to

>In article 000B...@ti.com, f...@ti.com (Fred J. McCall) writes:
>>That's right, and that's why you should listen to him (and to me, and to
>>everyone else telling you this). The REASON it is undefined is BECAUSE THE
>>STANDARD SAYS SO.
>
> Why?
>
>>They could have specified behaviour.
>
> Who are they? How could they have specified behaviour. Why didn't they?
>
>>They didn't.
>
> Why not?
>
>>Your
>>'reason' is sheer sophistry. After all, I can come up with more than one
>>'interpretation' for how something could have been implemented for almost any
>>language construct. That doesn't make them all undefined.
>
> Indeed it doesn't. So there is perhaps something that differentiates
> this construct from others, that caused the 'they' from the previous
> line to leave the behaviour undefined. What is that something?

Nope. This construct is only a particular case of a more general rule.
Here it is (ANSI classic 3.3):

Between the previous and next sequence point an object shall have
its stored value modified at most once by the evaluation of an
expression. Furthermore, the prior value shall be accessed only to
determine the value to be stored.
>

>I may regret this, but I'll jump in anyway. I accept that the behaviour
>of such a construct is undefined simply because the Standard says so. But
>isn't it legitimate for me to ask why the Standard leaves it undefined?

It isn't legitimate to ask us why the standard decided to leave it
undefined, because we didn't write the standard. Have you bothered to
read Chris Torek's contribution to this thread?

There is only one document trying to explain certain decisions of the
ANSI committee: the ANSI Rationale. Check the FAQ to find out how to get
it by FTP. If you can't find your answer there, don't ask us to guess
what was behind the ANSI X3J11 committee decisions.

Anyway, this information, while useful to satisfy your curiosity, is
completely irrelevant to C programming. You can be a very good car
driver without knowing why you have to drive on the right side of the
road in most countries, except a few.

Dan

Jos Horsmeier

unread,
Mar 20, 1995, 8:19:38 AM3/20/95
to
In article <D5JLG...@tigadmin.ml.com> ji...@nottingham.ml.com writes:
|In article 000B...@ti.com, f...@ti.com (Fred J. McCall) writes:

|>That's right, and that's why you should listen to him (and to me, and to
|>everyone else telling you this). The REASON it is undefined is BECAUSE THE
|>STANDARD SAYS SO.
|
| Why?
|
|>They could have specified behaviour.
|
| Who are they? How could they have specified behaviour. Why didn't they?
|
|>They didn't.
|
| Why not?
|
|>Your
|>'reason' is sheer sophistry. After all, I can come up with more than one
|>'interpretation' for how something could have been implemented for almost any
|>language construct. That doesn't make them all undefined.
|
| Indeed it doesn't. So there is perhaps something that differentiates
| this construct from others, that caused the 'they' from the previous
| line to leave the behaviour undefined. What is that something?
|
|
|I may regret this, but I'll jump in anyway. I accept that the behaviour
|of such a construct is undefined simply because the Standard says so. But
|isn't it legitimate for me to ask why the Standard leaves it undefined?

Of course it's legitimate to ask for a `why'. But nodbody but one of
the comittee members can give you a clear definite answer. My guess
(and please note, it's just a guess) is, that after they came up with
the concept of `sequence points' and the related behavior of side effects,
i.e. side effects can be considered `done' when a sequence point is
reached during program execution, _and_ after stating that the order
of evaluation of the operands in expressions was unspecified (like it
used to be in the pre-ANSI age), a `natural' consequence had to be
that two or more assignments to one object (all before the first
sequence point was reached) yields undefined behavior.

The only alternative would have been an exhaustive list of tedious
definitions describing all the wheres, hows and whens (and their
exceptions) if those multiple assignments would have resulted in
defined behavior ...

kind regards,

Jos aka j...@and.nl

Fred J. McCall

unread,
Mar 21, 1995, 7:15:04 AM3/21/95
to
In article <D5JLG...@tigadmin.ml.com> ji...@nottingham.ml.com (Jim Frohnhofer) writes:

>In article 000B...@ti.com, f...@ti.com (Fred J. McCall) writes:
>>That's right, and that's why you should listen to him (and to me, and to
>>everyone else telling you this). The REASON it is undefined is BECAUSE THE
>>STANDARD SAYS SO.

> Why?

Because it doesn't say something else.

>>They could have specified behaviour.

> Who are they?

The ANSI committee that wrote the Standard.

> How could they have specified behaviour.

By specifying a defined behaviour for the construct.

> Why didn't they?

Because they didn't.

>>They didn't.

> Why not?

Because.

>>Your
>>'reason' is sheer sophistry. After all, I can come up with more than one
>>'interpretation' for how something could have been implemented for almost any
>>language construct. That doesn't make them all undefined.

> Indeed it doesn't. So there is perhaps something that differentiates
> this construct from others, that caused the 'they' from the previous
> line to leave the behaviour undefined. What is that something?

No, there isn't. If there were, it might have gotten defined. However, 'this
construct' tries to change the value of a variable twice between sequence
points. This is undefined behaviour. It is undefined behaviour BECAUSE THE
STANDARD SAYS THAT TRYING TO CHANGE THE VALUE OF SOMETHING MORE THAN ONCE
BETWEEN SEQUENCE POINTS IS UNDEFINED BEHAVIOUR.

>I may regret this, but I'll jump in anyway. I accept that the behaviour
>of such a construct is undefined simply because the Standard says so. But
>isn't it legitimate for me to ask why the Standard leaves it undefined?

Of course it is. However, making up some 'reason' and then pointing to it and
saying that that is why is *not* 'legitimate' and it *is* what the person I
was responding to did. I suspect that the 'reason' it is undefined is that it
wasn't worth the trouble and effort a compiler would have to go through to
make it defined.

>As far as I know, it was created by a committee not brought down by Moses
>from the mountain top. If I want to become a better C programmer, won't
>it help me to know why the committee acted as it did.

No, it probably won't. Does it help you to become a better driver to know why
the metals in your car are formulated as they are?

>Similarly, can't I ask why the committee did what they did?

And if there is no reason other than that there was no good reason to require
compilers to make it 'defined'? You still come back to "because the Standard
says so".

Tanmoy Bhattacharya

unread,
Mar 21, 1995, 5:35:56 PM3/21/95
to
In article <D5qqC...@and.nl>, j...@and.nl (Jos Horsmeier) writes:
<snip>

|> |I may regret this, but I'll jump in anyway. I accept that the behaviour
|> |of such a construct is undefined simply because the Standard says so. But
|> |isn't it legitimate for me to ask why the Standard leaves it undefined?
|>
|> Of course it's legitimate to ask for a `why'. But nodbody but one of
|> the comittee members can give you a clear definite answer. My guess
<snip>

This question seems to have been answered pretty well by Chris Torek, Dan Pop
and now by Jos Horsmeier: I come in at this stage to show why I feel it is
not an unnecessary restriction. I hope this explanation will satisfy those
who think the rationale does not `rationalize' this enough. I am not and have
never been in anyway associated with any standardization committee ... I
simply use C.

Basically, in any high level programming language, one desires both
the clarity of expression and the possiblity of optimization. At some points,
the two can conflict: optimization might render certain unreadable constructs
extremely efficient. Most languages, to varying degrees, allow the compiler
to reorder source code `commands' to take advantage of the peculiarities of
the platform it is running on. Thus, for example, if I have two CPUs, and I
write `(x+y)*(v+w)', I _do_ want to allow one CPU to evaluate the (x+y), and
the other to evaluate the (v+w). So, I deliberately _want_ to keep the order
of the two additions undefined: but in this case it does not lead to any
difference.

What however should we do with `(*x)++ * (*y)++'? Should we send (*x)++ to
one CPU, and (*y)++ to another? If not, we loose efficiency. If we do, we are
in trouble if x and y point to the same place: what happens if the second CPU
tries to fetch *y write when the first CPU (which say was slightly faster
because it did not have to service some interrupt) was trying to store *x?

The standard wisely chose to leave such situations `undefined'. (In fact, I
believe they did not go far enough). They wanted to say, in effect, that when
you modify an object, do not expect the modification to take effect
immediately; and if you access a modified object, or modify it once again
before you are sure that the previous modification is over, you might
potentially get into problems with _simultaneous_ modification and access,
_simultaneous_ modifications, and the more common prosaic form of undefined
_order_ of modification and access etc. There are specific places where the
modification is guaranteed to have been finished: the obvious one being at
the end of a statement expression (Otherwise, writing a program would
become impossible). To sanctify a lot of common and useful usages, a few
other places were also chosen as `sequence points': a few are obviously
useful (the initializer and increment in the for statement), and a few others
stylistically common (controlling expression in if,switch,for,while etc.,
before ?, &&, || etc.).

It so happens that I do not see any reason for = to be a sequence point
(either after the rhs evaluation, or after the lhs evaluation). Thus in a[i]
= i++;, I do not feel that I know that the lhs i refers to the previous value
of i, nor do I think it is clearly the incremented value of i. I want to
allow the compiler full freedom to do the address calculation in a[i] and the
increment in i++ simultaneously in any way it pleases. So I want this to be
undefined.

Could the committee have decided otherwise? It sure could have. I would have
been unhappy with their decision, but not all users can be made happy all the
time. As has been repeatedly stated, they chose not to: and they _define_ the
language.

Hope this helps a bit. But, as I asked in another of these threads (or was it
the same one?), why does one _want_ to write i = i++? Does this idiom give any
new power or beauty to the code than the simpler i++? Or for those who want
to see an = for every assignment, than i+=1?

Cheers
Tanmoy
--
tan...@qcd.lanl.gov(128.165.23.46) DECNET: BETA::"tan...@lanl.gov"(1.218=1242)
Tanmoy Bhattacharya O:T-8(MS B285)LANL,NM87544-0285,USA H:#3,802,9 St,NM87545
Others see <gopher://yaleinfo.yale.edu:7700/00/Internet-People/internet-mail>,
<http://alpha.acast.nova.edu/cgi-bin/inmgq.pl>or<ftp://csd4.csd.uwm.edu/pub/
internetwork-mail-guide>. -- <http://nqcd.lanl.gov/people/tanmoy/tanmoy.html>
fax: 1 (505) 665 3003 voice: 1 (505) 665 4733 [ Home: 1 (505) 662 5596 ]

Steve Summit

unread,
Mar 21, 1995, 12:26:59 PM3/21/95
to
In article <D5JLG...@tigadmin.ml.com>, Jim Frohnhofer

(ji...@nottingham.ml.com) writes:
> In article 000B...@ti.com, f...@ti.com (Fred J. McCall) writes:
>> That's right, and that's why you should listen to him (and to me, and to
>> everyone else telling you this). The REASON it is undefined is BECAUSE THE
>> STANDARD SAYS SO.
>
> I may regret this, but I'll jump in anyway. I accept that the behaviour
> of such a construct is undefined simply because the Standard says so. But
> isn't it legitimate for me to ask why the Standard leaves it undefined?

It is, but you should probably be careful how you ask it.
If you're not careful (you were careful, but most people aren't),
it ends up sounding like you don't believe that something is
undefined, or that you believe -- and your compiler happens
to agree -- that it has a sensible meaning. But as long as
we're very clear in our heads that we're asking the abstract,
intellectual question "Why are these things undefined?", and not
anything at all practical like "How will these things behave in
practice?", we may proceed.

The first few answers I give won't be the ones you're looking
for, but towards the end I may present one which you'll find more
satisfying.

First of all, you might want to take a look at who's saying what.
I'll grant that statements such as Fred's above can be annoying.
I agree completely that it's usually very good to know the
reasons behind things. But if the people who have been posting
to comp.lang.c the longest, and who have been programming in C
for the longest and with the most success, keep saying "it's
undefined, it's undefined, quit worrying about why, just don't do
it, it's undefined", they might have a good reason, even if they
don't -- or can't -- say what is, and that might be a good enough
reason for you, too.

I've been programming in C for, oh, 15 years now. For at least
10 of those years, I've been regarded as somewhat of an expert.
For going on 5 of those years, I've been maintaining the
comp.lang.c FAQ list. I am someone who is usually incapable of
learning abstract facts unless I understand the reasons behind
them. When I used to study for math tests, I wouldn't memorize
formulas, I'd just make sure that I could rederive them if I
needed them. Yet for most of the 15 years I've been programming
in C, I simply could not have told you why i=i++ is undefined.
It's an ugly expression; it's meaningless to me; I don't know
what it does; I don't want to know what it does; I'd never write
it; I don't understand why anyone would write it; it's a mystery
to me why anyone cares what it does; if I ever encountered it in
code I was maintaining, I'd rewrite it. When I was learning C
from K&R1 in 1980 or whenever it was, one of their nice little
sentences, which they only say once, and which if you miss you're
sunk, leaped up off the page and wrapped itself around my brain
and has never let go:

Naturally, it is necessary to know what things to avoid,
but if you don't know *how* they are done on various
machines, that innocence may help to protect you.

As it happens, it's possible to read K&R *too* carefully here:
the discussion at the end of chapter 2 about a[i] = i++ suggests
that it's implementation-defined, and the word "unspecified"
appears in K&R2, while ANSI says that the behavior is undefined.
The sentence I've quoted above suggests not knowing how things
are done on various machines, while in fact what we really want
to know is that maybe they *can't* be done on various machines.
Nevertheless, the message -- that a bit of innocence may do you
good -- is in this case a good one.

That's my first answer. I realize that it's wholly unsatisfying
to anyone who's still interested in this question. On to answer
number two.

> As far as I know, it was created by a committee not brought down by Moses
> from the mountain top. If I want to become a better C programmer, won't
> it help me to know why the committee acted as it did.

Perhaps, but again, only if you're very careful.

Let's say you're wondering why i++ * i++ is undefined. Someone
explains that it's because no one felt like defining which order
the side effects happen in. That's a nice answer: it's a bit
incomplete and perhaps a bit incorrect, but it's certainly easy
to understand, and since you insisted on an answer you could
understand (as opposed to something inscrutable like "it's just
undefined; don't do it"), it's the kind of answer you're likely
to get.

So next week, you find yourself writing something like

i = 7;
printf("%d\n", i++ * i++);

and you say to yourself, "Whoah, that might be undefined.
How did that explanation go again? It's undefined... because
nobody felt like saying... which order the side effects happened
in. So either the first i gets incremented first, and it's 7
times 8 is 56, or the second i gets incremented first, and it's
8 times 7 is 56. Hey! It may be undefined, but I get a
predictable answer, so I can use the code after all!"

So in this case, knowing a reason why has not made you a better
programmer, it has made you a worse programmer, because some day
when you're not around to defend it (or when you are around, but
you don't have time to debug it), that code is going to print 49,
or maybe 42, or maybe "Floating point exception -- core dumped".

If, on the other hand, you didn't know why it was undefined,
just that it was undefined, you would have instead written

printf("%d\n", i * (i+1));
i += 2;

(or whatever it was that you meant), and your code would have
been portable, robust, and well-defined.

Now, some of you may be thinking that

printf("%d\n", i++ * i++);

is a ridiculous example which no one would ever write. That may
be true, but it's the example I use in the FAQ list (and it's the
oldest of the undefined-evaluation-order questions in the FAQ
list) because it illustrates, I hope better than a "real" example
would, the kind of contortions that people *do* get into when
they start thinking too hard (but not too carefully) about
undefined expressions. There was an actual question posted to
comp.lang.c years ago (which I could probably find in my archives
if I looked hard enough) in which the poster used essentially the
same argument: "the evaluation order may be undefined, but no
matter which order the compiler picks, I'll get the answer I
want", and that was the inspiration for the i++ * i++ question
(4.2 on the current list). (Remember, it's not the evaluation
order that's undefined, it's the entire expression that's
undefined.)

Two paragraphs back, I suggested that the programmer who did not
know why something was undefined might have been better off than
the programmer who did. I am not stating (not in the current
climate, anyway) that you should not know why things are
undefined. But if you insist on knowing, you are going to have
to get the full story, not just some simplistic justifications.
And you are going to have to be excruciatingly careful that you
don't use your knowledge of why something is undefined to try to
second-guess how a certain undefined construct (which you've
decided you simply have to use in your program) is going to
behave. Undefined behavior is slippery stuff: it really, truly
is undefined; it really, truly can do anything at all; yet some
people (particularly those who are always clamoring to know *why*
things are undefined) are always trying to salvage some remnants
of definedness out of an undefined situation, and are always
getting themselves in trouble, and end up convincing the people
who have to come along and pick up the mess that yes, it really
was a mistake trying to explain why it was undefined, and we
probably should have just said it was undefined because we said
it was, after all.

This has been answer number two, and I realize it's still not
satisfying, because I'm still suggesting that maybe you don't
want to know why.

For answer number three, I'll quit beating around the bush and
try to explain why, although I have to admit that, for me, the
answers from here on are going to get less satisfying, and less
nicely worded, because we get down into some realms that I don't
usually think about (because I really have taken to heart K&R's
advice about maintaining some innocence).

An international Standard like X3.159/ISO-9899 is a tremendously
difficult document to write, even for a relatively simple
programming language like C. When a Standard says something,
it must say it definitively and unambiguously. (When it is
inaccurate, it must be definitively inaccurate, and when it
contains any areas of doubt or uncertainty, they must be rigidly
defined areas of doubt or uncertainty.) The Standard must
withstand intense scrutiny, for many years, from all sorts of
observers, including language lawyers, professional nitpickers,
grudging ex-users of other languages, semicompetent implementors
of spiffola new compilers for scruffola old computers, and
xenophobic adherents of other sociopolitical systems. (If you
think that abstract constructions like programming languages are
inherently removed from sociopolitical concerns, you haven't
followed the crafting of any international Standards.)

Since it's so hard to specify things precisely enough for a
Standard like this, the wise Standard-writer (especially for a
Standard that hews to existing practice) won't specify anything
more than is necessary. Features that everyone will use (or that
someone might be reasonably expected to use) must be specified
precisely, but features that no sane person could be expected to
use in 6,000 years might be relegated to the dustbin, instead.
(Naturally, since we're being precise, we'll have to precisely
define the boundaries of the parts we've decided to be imprecise
about; the paraphrase above of Vroomfondel's demand from The
Hitchhiker's Guide to the Galaxy is not facetious.)

In practice, you can only tell what a computer program has done
when it causes a side effect. In a nutshell, then, what a
Standard for a programming language does is to define the mapping
between the programs you write and the side effects they produce.
Consequently, we are very concerned with side effects: how
they're expressed in our programs, and how the Standard defines
them to behave.

The fragment

int i;
i = 7;
printf("%d\n", i);

contains two obvious side effects, and it is blatantly obvious
what their effect should be, and what the Standard says agrees
with what you think they should do.

The fragment

int a[10] = {0}, i = 1;
i = i++;
a[i] = i++;
printf("%d %d %d %d\n", i, a[1], a[2], a[3]);

contains a few more side effects, but (I assert) it is *not*
obvious how they should behave. What does the second line do?
In the third line, do we decide which cell of a[] we assign to
before or after we increment i again? Plenty of people can
probably come up with plenty of opinions of how this fragment
ought to work, but they probably won't all agree with each other,
as the situation is not nearly so clear-cut.

Furthermore, a Standard obviously cannot talk about individual
program fragments like i = i++ and a[i] = i++, because there are
an infinite number of those. It must make general prescriptions
about how the various primitive elements of the language behave,
which we then use in combination to determine how real programs
behave. If you think you know what a[i] = i++ should do, you
can't just say that; instead you have to come up with a general
statement which says how *all* expressions which modify and then
use the same object should act, and you have to convince yourself
that this rule is appropriate not only for the a[i] = i++ case
you thought about but also for all the other expressions
(infinitely many of them, remember) that you did *not* think
about, *and* you have to convince a bunch of other people of your
conviction.

The people writing the C Standard decided that they could not do
that. Instead, they decided that expressions such as a[i] = i++
and i++ * i++ and i = i++ would be undefined. They decided this
because these expressions are too hard to define and too stupid
to be worth defining. They came up with some definitions (no
small feat in itself) of which expressions this undefinedness
applies to. You've seen these definitions; they're the ones
that say

Between the previous and next sequence point an object
shall have its stored value modified at most once by the
evaluation of an expression. Furthermore, the prior
value shall be accessed only to determine the value to
be stored.

Now, I'll grant that these definitions are at least as hard to
understand as expressions such as a[i] = i++. But there are
plenty of more complicated expressions which we can't begin to
make sense of (or even decide if they make any sense) without
these definitions. Perhaps I'll say more about them later, but
for the moment we're still trying to answer the question of why
some things (such as the expressions not defined by the two
definitions quoted above) are undefined, and my opinion is, as I
stated above: because they're too hard to define, and too stupid
to be worth defining. (If you're still counting, call this
answer number three.)

Now, you may think that I'm being overly pessimistic. You may
think that it's easy to define what a[i] = i++ or i++ * i++ or
i = i++ should do. Perhaps you think they should be evaluated
in exactly the order suggested by precedence and associativity.
Perhaps you think that i++ should increment i immediately after
giving up i's value and before evaluating any of the rest of the
expression. (These rules would say that the incremented value of
i is used to decide which cell of a[] to assign to, and that the
left-hand i++ in i++ * i++ happens first, and that i = i++ ends
up -- here's a surprise -- being exactly equivalent to i = i,
unless perhaps if i is volatile.) But -- and you're going to
have to take my word for it here, because I'm taking other
people's word for it -- these hypothetical "well-defined"
expression rules, though they're easy enough to state and
probably precise enough and probably comprehensive for the
cases we're interested in, would result in significantly poorer
performance than pre-ANSI C traditionally had and that we're
used to. Optimizing compilers would have to generate code which
evaluated expressions in little itsy bitsy steps, in lockstep
with the precedence- and associativity-based parse. They would
not be able to rearrange parts of the expression to make the best
use of the target machine's instruction repertoire or available
registers or pipelining or parallelization or whatnot.

When people talk about why it's good that an expression like
i++ * i++ is undefined, they usually speak of modern, parallel
machines which might get really confused if they try to do, not
the left-hand i++ first or the right-hand one first, but instead
both at once somehow. Instead of that example, let's imagine a
very simple CPU, analogous to a four-function calculator with
some memory registers. Let's play compiler, and imagine what
buttons on the calculator we'll push, operating under the
"well-defined" rules of the previous paragraph.

Since the (hypothetical) "well-defined" rules tell us exactly
which order to evaluate the expression in, our task is
straightforward. First, the left-hand side of the multiplication
operator: the value we want to multiply is i's previous value.
Whoops, before we can think about doing the multiplication, the
rules say we have to do the increment. Whoops, once we do the
increment, we'll have lost the previous value. So we recall
from i, store the value in a temporary register, add one to to
the value, and store it back in i. Now we can recall from the
temporary, and do the multiplication... no. Because first we
have to do the same thing on the right-hand side: recall from i,
store it in a second temporary, add one to it, and store it back
in i. Now, finally, we can recall the two values from the two
temporaries and do the multiplication.

If we remove the (still hypothetical, just for the purposes of
this article, not part of Standard C) "well-defined" rules, and
revert to ANSI's rules, under which we only have to make sure
that the increments to i happen sometime before the next sequence
point, look how much easier things become: Recall from i. Make a
note to increment its value later. Multiply it by: recall from i
again, make a note to increment it later. Now we've got the
product, do whatever we have to with it. We've still got these
two notes to increment i, so handle them, and we're done.

I'd never actually gone through the analysis in this level of
detail until just now, but this is exactly how the example

int i = 7;
printf("%d\n", i++ * i++);

from question 4.2 of the FAQ list could print 49 instead of 56.
(No, I'm not going to come up with a scenario under which it
could print 42.)

So, if you're still with me (and after 300 lines, I can see how
you might not be, but if you're one of the people who's been
insisting on a reason why, you better be :-) ), here is my
fourth, last answer: these things are undefined because if you
made them defined, compilers would have to be paranoid and
generate lockstep code which would be bulkier or slower or both.

Having come this far, I have to repeat that this last answer
isn't one I'm particularly pleased with, partly because I'm not a
code generation expert, and partly because I don't usually worry
about efficiency very much. (On the other hand, it doesn't
matter whether I'm pleased with it, or whether you're pleased
with it either; it *is* one of the reasons.) You're probably
also still harboring some doubts; you may be thinking that a
compiler would only have to use the slow, bulky, lockstep code
for expressions with multiple side effects, which many people
(even some of the Doubting Thomases) agree that we shouldn't be
writing anyway. Perhaps you're right. Perhaps we could have our
cake and eat it too; perhaps we could have blazingly efficient
code generated for polite little expressions and still have
defined behavior for rogue ones. Perhaps we could, but not
under the current Standard: it still *does* say that the rogue
expressions are undefined. But the C Standard is under revision:
perhaps, if this is important enough to you, you can convince the
committee to pronounce defined behavior upon the rogue
expressions, too. Good luck.

Finally, if you've read this far, do me a favor. I've spent some
time writing this up, not because I had nothing better to do
today, but because I do like to try to come up with ways of
answering these questions. Please (all of you, not just Jim) let
me know if this explanation worked for you, or not; or if some of
it worked and some didn't, which bits did and which bits didn't.
Thanks.

Steve Summit
s...@eskimo.com

Larry Weiss

unread,
Mar 21, 1995, 3:16:36 PM3/21/95
to
s...@eskimo.com (Steve Summit) writes:
>applies to. You've seen these definitions; they're the ones
>that say

> Between the previous and next sequence point an object
> shall have its stored value modified at most once by the
> evaluation of an expression. Furthermore, the prior
> value shall be accessed only to determine the value to
> be stored.

Do any compilers generate diagnostics for the most blatant
(i = i++; for example) attempts to cause more than one
modification of a stored value between two consecutive
sequence points?
--
Larry Weiss, l...@oc.com
214/888-0471

Mark Charette

unread,
Mar 21, 1995, 10:34:07 PM3/21/95
to
As a former member of an ANSI Standards committee (X3H3.1), thanks for the
lucid explanation. Better than I'd ever come up with.

--------------------------------------------------------------------------------
Mark Charette "Don't crush that dwarf; hand me the pliers"
MIKA Systems, Inc. - Firesign Theater
17197 N. Laurel Park Dr Suite 115
Livonia, MI 48152 char...@mika.com

john c henry

unread,
Mar 21, 1995, 3:49:22 PM3/21/95
to
In article <D5swG...@eskimo.com>, s...@eskimo.com says...

>
>It is, but you should probably be careful how you ask it.
[snip++]

That is THE most complete answer I have ever seen on the subject of
why undefined means undefined! Thank you for a very enlightening
discussion, I really enjoyed it. So will many of my coworkers when
they: a) Ask me the same question, or b) try to use the constructs
mentioned in the text (which I have seen once or twice |> ).

john

--
>--0--< >--0--<
If It's Politically Correct, It's a lie.
Do not confuse my opinions with those of Intel Corp, or vice versa!

Mike Cutlip

unread,
Mar 22, 1995, 4:02:13 PM3/22/95
to
Steve,

As a relative newcomer to C, who came from ASM, I often ponder
over some of the overly complex compound statements I come across in some
peoples code. I appreciate your thorough and eloquent answer to the
question of using ambiguous, self-serving (my opinion) code instead of
just saying what you mean.
Thanx
Mike Cutlip

dma...@freenet.edmonton.ab.ca

unread,
Mar 22, 1995, 1:47:15 PM3/22/95
to
Thank you! I've archived that explanation of why certain things are best left
undefined in C. Maybe it should be made an addendum to the FAQ?

I've only skimmed it so far, but it certainly seems to address the point FAR
better than I could.

I guess my attitude could be summed up by saying that I don't like
answers of the form "You can't do x because y said so" without further
justification, in ANY field, not just programming. There are
circumstances where blind faith is necessary, but being atheist I like to
avoid it where possible!

John Bickers

unread,
Mar 22, 1995, 6:22:05 PM3/22/95
to
Quoted from <D5JLG...@tigadmin.ml.com> by ji...@nottingham.ml.com (Jim Frohnhofer):

> CONSTITUTION SAYS SO. Does it occur to you, that perhaps what I want to
> know is why the writers of the Constitution chose to do it that way?

Excellent example.

> Similarly, can't I ask why the committee did what they did?

Of course you can. However, such a question might best be directed
to the committee itself, or to a newsgroup (is there a comp.ansi.c
newsgroup?) where the standard is discussed at this level.

IMHO, far too much discussion about the standard occurs here that
should be taking place in a comp.ansi.c.

My guess as to why the committee made the behaviour undefined for
this specific case would be that not doing so would have
conflicted with their concept of "sequence points", as explained
in the FAQ.

> Jim Frohnhofer
--
*** Count Templar, ELITE (FM-287) jbic...@templar.actrix.gen.nz ***
*** "Radioactivity - It's in the air, for you and for me" - Kraftwerk ***

Dan Pop

unread,
Mar 22, 1995, 9:59:31 PM3/22/95
to

>Quoted from <D5JLG...@tigadmin.ml.com> by ji...@nottingham.ml.com (Jim Frohnhofer):
>

>> Similarly, can't I ask why the committee did what they did?
>
> Of course you can. However, such a question might best be directed
> to the committee itself, or to a newsgroup (is there a comp.ansi.c
> newsgroup?) where the standard is discussed at this level.
>
> IMHO, far too much discussion about the standard occurs here that
> should be taking place in a comp.ansi.c.
>

Such a group exists: comp.std.c. Have a look at it and you'll see that
the discussions about the standard here are at a completely different
level than those in c.s.c.

Rob Ewan

unread,
Mar 23, 1995, 12:26:44 PM3/23/95
to
In <D5swG...@eskimo.com>, s...@eskimo.com (Steve Summit) writes:
[ a good explanation of the UNDEFINED i = i++]
>... Please (all of you, not just Jim) let

>me know if this explanation worked for you, or not; or if some of
>it worked and some didn't, which bits did and which bits didn't.
>Thanks.

Steve,
I just read your answer to why i = i++ is undefined. It is the best
description I have read, and I thank you for sharing it with all of us.

If I may summarize,
The behaviour is undefined because the committee which standardized C chose
to make it undefined.

They chose to make it undefined in order to
- avoid trying to ensure that whatever definition they came up with
would work under ALL circumstances
AND
- avoid having the standard make implementation decisions instead
of the compiler makers.
(Note that this also means that no amount of reasoning when using
the expression guarantees that some compiler maker would follow the
same reasoning, so I probably can't outguess the compiler maker. The
compiler maker may have simply said "It's UNDEFINED, who cares what
it does" and not even designed for it or tested for it)

I realize that I am over-simplifying it, but the net effect is that I can
now say (to myself)

1.) Don't use expressions like 'i = i++;' because they are UNDEFINED

2.) The decision to make them UNDEFINED was not arbitrary, and I have seen
enough of it to understand some of the reasoning (if there were a test, I
believe I could 'rederive' the reasons :) ).


+--------------------------------------------------------+
| Rob Ewan (rae...@idirect.com) | The views expressed are my own |
| Sufficiently Advanced Technology | and do not necessarily reflect |
| Toronto, Ont | those of my employer |
+--------------------------------------------------------+

Warner Pel

unread,
Mar 27, 1995, 4:57:44 PM3/27/95
to

In article <3knc74$p...@pssparc2.oc.com> l...@pssparc2.oc.com (Larry Weiss) writes:
>
> Do any compilers generate diagnostics for the most blatant
> (i = i++; for example) attempts to cause more than one
> modification of a stored value between two consecutive
> sequence points?
>

I am not aware of any compilers that will warn you, however:
the LCLint program that is available by ftp from MIT will warn you
about this and a lot more.

information: http://larch-www.lcs.mit.edu:8001/~evs/install.html
ftp-archive: ftp://larch.lcs.mit.edu/pub/Larch/lclint

/* example */

maggie% uname -a
SunOS maggie 4.1.3_U1 1 sun4m
maggie% cat junk.c
#include <stdio.h>

int
main()
{
int i = 0;
i = i++;
printf ("%d\n", i);
return (0);
}

maggie% lclint junk.c
LCLint 1.4c --- Wed Feb 1 17:16:26 NZDT 1995

junk.c:7,11: Expression has undefined behavior (i is modified by i++): i = i++

Finished LCLint checking --- 1 code error found, expected 0
maggie%

/* end example */

Warner
--
Warner Pel | "I've got plenty of common sense ---
wp...@clear.co.nz | I just choose to ignore it"
ph: + 64 9 912-4579 | Calvin
*** PGP key available on request ***

0 new messages