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

a = b++ + b;

7 views
Skip to first unread message

George C. Lindauer

unread,
Apr 5, 1997, 3:00:00 AM4/5/97
to

a = b++ + b;

Does ansi C specify the evaluation ordering? Clearly I can get two
different results for the above expression depending on WHEN I apply
the postincrement. It would obviously be nice to evaluate it in left-to
right order... unfortunately in this case and many similar cases I
can generate better code by going right to left. I guess what I'm
asking is can I postpone pre and post-increments until after the rest
of the expression is evaluated?

David

Brian Ross

unread,
Apr 5, 1997, 3:00:00 AM4/5/97
to

George C. Lindauer wrote:
>
> a = b++ + b;

My guess is that this should expand to:

a = b + b;
b++;

if it had been a = ++b + b, it would be:

b++;
a = b + b;

--
Brian Ross (br...@engsoc.carleton.ca)

Lawrence Kirby

unread,
Apr 6, 1997, 4:00:00 AM4/6/97
to

In article <5i6mh9$icg$1...@hermes-x.louisville.edu>

gcli...@starbase.spd.louisville.edu "George C. Lindauer" writes:

>a = b++ + b;
>

>Does ansi C specify the evaluation ordering?

It doesn't specify *anything* about the behaviour of the expression above -
it has undefined behaviour which means that anything can happen; it could
fail to compile it could fault when executed, it might come up with the
answer 42, format your hard disk and so on. You are not permitted to
modify the same object twice or modify an object and read the value of the
object (unless it is used to calculate the new value to be written) between
sequence points.

> Clearly I can get two
>different results for the above expression depending on WHEN I apply
>the postincrement. It would obviously be nice to evaluate it in left-to
>right order... unfortunately in this case and many similar cases I
>can generate better code by going right to left.

First of all define the result you want. There's no point in discussing how
you will evaluate an expression if you don't get the right result. The
expression above doesn't tell us what you actually wanted

> I guess what I'm
>asking is can I postpone pre and post-increments until after the rest
>of the expression is evaluated?

You need to introduce a sequence point. You could write:

a = 2*b + 1; b++; /* assuming that is the result you wanted */

or, in a single expression:

a = 2*b + 1, b++;

where , here is the comma operator which definmes a sequence point. Other
operators that define sequence points are && || and ? : all after the first
operand is evaluated. There is also a sequence point just before a function
call is made (i.e. after the function designator and arguments are evaluated).

Make sure you read the FAQ, it has a lot of information on this area as
well as many others. You can ftp the FAQ from rtfm.mit.edu under
/pub/usenet/comp.lang.c

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


John Bode

unread,
Apr 6, 1997, 4:00:00 AM4/6/97
to

In article <3346F4...@engsoc.carleton.ca>, br...@engsoc.carleton.ca wrote:

> George C. Lindauer wrote:
> >
> > a = b++ + b;
>

> My guess is that this should expand to:
>
> a = b + b;
> b++;
>
> if it had been a = ++b + b, it would be:
>
> b++;
> a = b + b;
>

I don't think this is true at all -- in fact, I think both expressions
invoke undefined behavior, meaning anything can happen.

From the abridged FAQ:

3.1: Why doesn't the code "a[i] = i++;" work?

A: The variable i is both referenced and modified in the same
expression.

For both cases above, b is referenced and modified in the same expression.

3.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: The operations implied by the postincrement and postdecrement
operators ++ and -- are performed at some time after the
operand's former values are yielded and before the end of the
expression, but not necessarily immediately after, or before
other parts of the expression are evaluated.

3.3: How could the code "int i = 3; i = i++;" ever give 7?

A: Undefined behavior means *anything* can happen.

3.4: Don't precedence and parentheses dictate order of evaluation?

A: Operator precedence and explicit parentheses impose only a
partial ordering on the evaluation of an expression, which does
not generally include the order of side effects.

--
John Bode
"Paranoia is just reality on a finer scale" -- Strange Days

Arnold Woodworth

unread,
Apr 6, 1997, 4:00:00 AM4/6/97
to

gcli...@starbase.spd.louisville.edu (George C. Lindauer) wrote:

>a = b++ + b;

Question:
What is the purpose of writing this expression??
What were you trying to accomplish??

Alicia Carla Longstreet

unread,
Apr 7, 1997, 3:00:00 AM4/7/97
to

Arnold Woodworth wrote:


> George C. Lindauer wrote:

> >a = b++ + b;

> Question:
> What is the purpose of writing this expression??
> What were you trying to accomplish??

If his goal was to produce undefined behavior, he succeeded!!! Anyway,
I believe he actually used this 'expression' in a program, it did not
produce the result he 'expected' (sic) and he was asking why.

--
********************************************
* Alicia Carla Longstreet ca...@ici.net
********************************************
The money spent on an abortion,
as any woman may find out,
can better be spent on other things,
like taking the kids to an amusment park, or on vacation.

Stephan Wilms

unread,
Apr 8, 1997, 3:00:00 AM4/8/97
to

Arnold Woodworth wrote:

>
> gcli...@starbase.spd.louisville.edu (George C. Lindauer) wrote:
>
> >a = b++ + b;
>
> Question:
> What is the purpose of writing this expression??
> What were you trying to accomplish??

The purpose was to accomplish undefined results. It is not allowed to
access the same value twice between sequence points.

Stephan

Stephan Wilms

unread,
Apr 8, 1997, 3:00:00 AM4/8/97
to

Brian Ross wrote:

>
> George C. Lindauer wrote:
> >
> > a = b++ + b;
>
> My guess is that this should expand to:
>
> a = b + b;
> b++;
>
> if it had been a = ++b + b, it would be:
>
> b++;
> a = b + b;
>
> --
> Brian Ross (br...@engsoc.carleton.ca)

WRONG on both occasions. Please read the other replies in this thread
AND
you might want to scan the c.l.c FAQ for "sequence points".

Stephan

Brian Ross

unread,
Apr 8, 1997, 3:00:00 AM4/8/97
to

Thats funny.. I tried it on my compiler (BC++3.1) and funny
enough it does exactly what I said it would do.

so does:

i = 0;
a = i++ + i++;
a gets assigned 0;

i = 0;
a = ++i + i++;
a gets assigned 2;

i = 0;
a = ++i + ++i;
a gets assigned 4;

I see nothing unexpected about this. I don't care whether is
'non standard' or whatever, the fact is that it works.

--
Brian Ross (br...@engsoc.carleton.ca)

Goran Larsson

unread,
Apr 8, 1997, 3:00:00 AM4/8/97
to

In article <334A11...@engsoc.carleton.ca>,

Brian Ross <br...@engsoc.carleton.ca> wrote:
| i = 0;
| a = ++i + ++i;
| a gets assigned 4;
|
| I see nothing unexpected about this. I don't care whether is
| 'non standard' or whatever, the fact is that it works.

Picking up my black book and writing down:

Never hire Brian Ross, ever.
Never use a program written by Brian Ross.
Never trust products from the company that hires Brian Ross.

--
Goran Larsson mailto:hoh @ approve . se
I was an atheist, http://home1.swipnet . se/%7Ew-12153/
until I found out I was God.

Jens Schweikhardt

unread,
Apr 8, 1997, 3:00:00 AM4/8/97
to

In article <334A11...@engsoc.carleton.ca> br...@engsoc.carleton.ca writes:
# Stephan Wilms wrote:
# >
# > Brian Ross wrote:
# > >
# > > George C. Lindauer wrote:
# > > >
# > > > a = b++ + b;
# > >
# > > My guess is that this should expand to:
# > >
# > > a = b + b;
# > > b++;
# > >
# > > if it had been a = ++b + b, it would be:
# > >
# > > b++;
# > > a = b + b;
# > >
# > > --
# > > Brian Ross (br...@engsoc.carleton.ca)
# >
# > WRONG on both occasions. Please read the other replies in this thread
# > AND
# > you might want to scan the c.l.c FAQ for "sequence points".
#
# Thats funny.. I tried it on my compiler (BC++3.1) and funny
# enough it does exactly what I said it would do.

So what? I could claim that all odd numbers greater than 1 are
primes. It's true for 3, 5, and 7. Remember, just because it
works on your platform (using compiler X, options Y, OS Z,...)
does by no means imply 'it works'. Insisting on it despite this
knowledge is sheer ignorance.

# so does:
#
# i = 0;
# a = i++ + i++;
# a gets assigned 0;

What would you expect on a multi processor machine where
the first and second i++ are evaluated on different processors?
What if such a system took it for granted that it could write
back results from any processor because it need not worry
about concurrent accesses to i?

# i = 0;
# a = ++i + i++;
# a gets assigned 2;

See above.

# i = 0;
# a = ++i + ++i;
# a gets assigned 4;

See above.

# I see nothing unexpected about this.

Because your view is too narrow. Look past your current horizon
and you'll see the difference.

# I don't care whether is 'non standard' or whatever,

How ignorant. What does it buy you? Nothing. Is there potential for
trouble? Certainly. If you were a contract programmer and I were your
boss I'd fire you right away.

# the fact is that it works.

On *your* system. Today. With exactly these options. With exactly
this compiler version. With your current revision of the OS and
hardware. Any change in these parameters has the potential to
break your code. I just don't get it why anyone can be so ignorant.

# --
# Brian Ross (br...@engsoc.carleton.ca)

Regards,

Jens
--
Jens Schweikhardt http://www.uni-stuttgart.de/People/schweikhardt/home.html
SIGSIG -- signature too long (core dumped)

Peter Seebach

unread,
Apr 8, 1997, 3:00:00 AM4/8/97
to

Abstract: Why I Would Never Hire Brian Ross

>Thats funny.. I tried it on my compiler (BC++3.1) and funny

>enough it does exactly what I said it would do.

How amazing! It's almost as though, if you learn from one compiler, you will
sometimes be able to predict that compiler.

Did you even read what the man wrote? READ THE FAQ, MORON. Until you do so,
you are inserting ever-larger boots into your mouth, which is quite
impressive, but really doesn't help your reputation. It certainly won't help
the newbies who are *trying* to learn something here...

>I see nothing unexpected about this.

Then you are a bloody fool. You do not know C, and when someone helpfully
points out to you that your "understanding" is not universally useful, you
just fall back on "well it works here". I certainly hope you're not an
engineer; I can just see you explaining that the bridge worked fine when you
drove your Geo Metro across it.

>I don't care whether is

>'non standard' or whatever, the fact is that it works.

No, the *FACT* is that it does not "work"; for us to say that "it works",
we must be able to show that it works *reliably*. It must work from day to
day, from compiler to compiler, from machine to machine.

There is at least one compiler which complains about the error in this code;
as technology improves, there will be more. Certainly, however, anyone who
says "I don't care whether this is standard, it works" based on *ONE* compiler
is never working *NEAR* any project I'm on; I'd quit before I'd work with
someone that bad.

Grow up, get a clue, and in the mean time
SHUT THE HELL UP
until you've read the FAQ. You're wasting my time and everyone else's with
this crap. The time I spent posting this would otherwise have been spent
answering a real question. Happy?

>Brian Ross (br...@engsoc.carleton.ca)

I hope the "eng" doesn't stand for "engineer".

-s
--
Copyright 1997 Peter Seebach - seebs at solon.com - C/Unix Wizard
I am not actually gla...@nancynet.com but junk mail is accepted there.
The *other* C FAQ, the hacker FAQ, et al. http://www.solon.com/~seebs
Unsolicited email (junk mail and ads) is unwelcome, and will be billed for.

John Bode

unread,
Apr 8, 1997, 3:00:00 AM4/8/97
to

In article <334A11...@engsoc.carleton.ca>, br...@engsoc.carleton.ca wrote:

[zap]

> Thats funny.. I tried it on my compiler (BC++3.1) and funny
> enough it does exactly what I said it would do.
>

> so does:
>
> i = 0;

> a = i++ + i++;

> a gets assigned 0;
>
> i = 0;

> a = ++i + i++;

> a gets assigned 2;
>
> i = 0;

> a = ++i + ++i;

> a gets assigned 4;
>
> I see nothing unexpected about this. I don't care whether is

> 'non standard' or whatever, the fact is that it works.
>

Okay, let's try this another way. One would expect that the statement

a = ++i + ++i;

would be equivalent to the statements

a = ++i;
a = a + ++i;

So let's assign 0 to i and try it out. Here are the results I get:

a = ++i + ++i (4)
a = ++i; a = a + ++i (3)

I get two different answers. I expect 3 to be correct, since I'm adding
++i (1) to ++i (2). But i = 0, a = ++i + ++i yields 4. Ask yourself how
that can happen. If you look at the value of i after both versions, it is
2.

So a = ++i + ++i *doesn't* work as expected. Why? Because it invokes
undefined behavior. I don't care what it does on your machine, the fact is
that because it is undefined, you cannot guarantee that it will work
everywhere the same way.

For anyone who's interested, here are the results of my tests and the
program that generated them (the value of i shown is the value after the
expressions have been evaluated):

i = 2, a = i++ + i++ (1)
i = 2, a = i++; a = a + i++ (1)
i = 2, a = ++i + i++ (2)
i = 2, a = ++i; a = a + i++ (2)
i = 2, a = ++i + ++i (4)
i = 2, a = ++i; a = a + ++i (3)
i = 2, a = i++ + ++i (3)
i = 2, a = i++; a = a + ++i (2)


#include <stdio.h>

int main()
{
int a, b, i;

i = 0;


a = i++ + i++;

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

i = 0;
a = i++;
a = a + i++;
printf ("i = %d, a = i++; a = a + i++ (%d)\n", i, a);

i = 0;


a = ++i + i++;

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

i = 0;
a = ++i;
a = a + i++;
printf ("i = %d, a = ++i; a = a + i++ (%d)\n", i, a);

i = 0;


a = ++i + ++i;

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

i = 0;
a = ++i;
a = a + ++i;
printf ("i = %d, a = ++i; a = a + ++i (%d)\n", i, a);

i = 0;
a = i++ + ++i;
printf ("i = %d, a = i++ + ++i (%d)\n", i, a);

i = 0;
a = i++;
a = a + ++i;
printf ("i = %d, a = i++; a = a + ++i (%d)\n", i, a);

return 0;

Lawrence Kirby

unread,
Apr 8, 1997, 3:00:00 AM4/8/97
to

In article <334A11...@engsoc.carleton.ca>
br...@engsoc.carleton.ca "Brian Ross" writes:

...

>Thats funny.. I tried it on my compiler (BC++3.1) and funny
>enough it does exactly what I said it would do.

Which of course proves nothing. Undefined behaviour means anything can
happen including what you expected. Unfortunately it doesn't guarantee
it will happen consistently. Try your code on different compilers or even
using different optimisation options on the compiler you have and there is
a good chance that you will get different results. Another problem is that
anybody else reading your code will have no idea what you actually wanted.

>so does:
>
>i = 0;
>a = i++ + i++;
>a gets assigned 0;

Don't forget the final value of i in this and the expresisons that follow.
One compiler here set a to 1 when compiled without optimisations and to 0
when compiled with optimisations. You appear to want:

a = 2*i; i+=2;

here, why not make your intentions clear?

>i = 0;
>a = ++i + i++;
>a gets assigned 2;
>
>i = 0;
>a = ++i + ++i;
>a gets assigned 4;

The same compiler assigned a to 3 in this expression.

>I see nothing unexpected about this. I don't care whether is
>'non standard' or whatever, the fact is that it works.

The point is that the expression is meaningless, anything the compiler does
is correct. If you ask different people to tell you what they think
that expression means (assuming they don't know it is undefined) you will
get different answers. If you have expressions like that embedded in your
code and you move to a different compiler, compiler version or just
optimisation level you are most likely to be in trouble.

John Winters

unread,
Apr 8, 1997, 3:00:00 AM4/8/97
to
>Stephan Wilms wrote:
>>
>> Brian Ross wrote:
>> >
>> > George C. Lindauer wrote:
>> > >
>> > > a = b++ + b;
>> >
>> > My guess is that this should expand to:
>> >
>> > a = b + b;
>> > b++;

>> >
>> > if it had been a = ++b + b, it would be:
>> >
>> > b++;

>> > a = b + b;
>> >
>> > --
>> > Brian Ross (br...@engsoc.carleton.ca)

>>
>> WRONG on both occasions. Please read the other replies in this thread
>> AND

>> you might want to scan the c.l.c FAQ for "sequence points".
>
>Thats funny.. I tried it on my compiler (BC++3.1) and funny
>enough it does exactly what I said it would do.

The man said look at the FAQ. Why didn't you?

John

--
John Winters. Wallingford, Oxon, England.

Chris Engebretson

unread,
Apr 8, 1997, 3:00:00 AM4/8/97
to

In article <334A11...@engsoc.carleton.ca>, Brian Ross <br...@engsoc.carleton.ca> writes:

|> Thats funny.. I tried it on my compiler (BC++3.1) and funny
|> enough it does exactly what I said it would do.

Magnificent! Borland is to be commended!

|> so does:


|>
|> a = i++ + i++;

|> a = ++i + i++;

|> a = ++i + ++i;

Astounding! Truly breathtaking.

|> I see nothing unexpected about this. I don't care whether is
|> 'non standard' or whatever, the fact is that it works.

Well then, by God, you just write your code the way that you see fit.
Never mind the combined C programming knowledge and experience of many
of the comp.lang.c regulars .. no bunch of whining pedants is going
to tell *you* what to do.

By your shocking evidence of Borland's results, you have clearly
proved that ISO/IEC 9899:1990's references to such esoteric concepts
as "sequence points" and "undefined behavior" are nothing but lies
and falsehoods spread to confuse massive amounts of C programmers.

Thanks for the clarification.

--
Chris Engebretson, USGS/NMD U|S E-mail: enge...@usgs.gov
EROS Data Center -+- Telephone: (605) 594-6829
Sioux Falls, SD 57198 G|S Fax: (605) 594-6490
My opinions given here are not necessarily those of the USGS.

Kaz Kylheku

unread,
Apr 8, 1997, 3:00:00 AM4/8/97
to

In article <334A11...@engsoc.carleton.ca>,
Brian Ross <br...@engsoc.carleton.ca> wrote:

>i = 0;


>a = ++i + ++i;

>a gets assigned 4;


>
>I see nothing unexpected about this. I don't care whether is
>'non standard' or whatever, the fact is that it works.

Hahahah!

You need to learn a few things about logic. Given the statement

``If I meet the preconditions that make my program well defined, then I get
the expected results.''

can we conclude that

``If I get the expected results, I meet the preconditions that
make my program well defined.''

No. This inference error is informally known as ``assuming the converse''.

The fact is, if you invoke undefined behavior, it means that no requirements
are imposed on what should happen. Your program may behave erratically,
terminate with a diagnostic message, or even produce the expected results by
coincidence. It can also behave in a manner that is documented by the
implementation as an extension to the language and is characteristic of
that implementation.

Unless your C implementation precisely documents how expressions like a = ++i +
i++ are translated, you are, for all intents and purposes, getting the results
by fluke. In that case, neither the language nor your implementation give any
guarantees. The behavior may change with the next version of the same
development tools. It may be different if pointers are involved:

*pa = ++(*pi) + (*pi)++;

It may vary with the placement of the expression, with various parameters that
influence the compiler such as optimization settings and so on.


>Brian Ross (br...@engsoc.carleton.ca)

Let me guess, engineering undergrad? Or English major? ;)

Kaz Kylheku

unread,
Apr 8, 1997, 3:00:00 AM4/8/97
to

In article <3346F4...@engsoc.carleton.ca>,

Brian Ross <br...@engsoc.carleton.ca> wrote:
>George C. Lindauer wrote:
>>
>> a = b++ + b;
>
>My guess is that this should expand to:
>
>a = b + b;
>b++;
>
>if it had been a = ++b + b, it would be:
>
>b++;

Why would you guess this? The C language does not specify the order
of evaluation of the operands of the + operator. If we are going
to guess, why not this:

a = b; /* get right operand */
b++; /* increment left operand */
a += b; /* add in left operand */

>a = b + b;

No such expansions are features of the C language semantics. The meaning
of side effects cannot be explained using clever expansions that transform
statement sequences into ``equivalent'' sequences.

Steve Summit

unread,
Apr 8, 1997, 3:00:00 AM4/8/97
to

In article <334A11...@engsoc.carleton.ca>,

br...@engsoc.carleton.ca writes:
> Thats funny.. I tried it on my compiler (BC++3.1) and funny
> enough it does exactly what I said it would do.

That's funny. I tried those examples on two compilers of mine,
and they all did exactly what *I* expected, which was something
completely different. What does that tell us?

> I see nothing unexpected about this. I don't care whether is
> 'non standard' or whatever, the fact is that it works.

The fact is that it "works" *for you*, under *this one compiler*.
How sure are you that it will work everywhere?

Steve Summit
s...@eskimo.com

P.S. See also http://www.eskimo.com/~scs/readings/correctness.950817.html .

Kaz Kylheku

unread,
Apr 8, 1997, 3:00:00 AM4/8/97
to

In article <E8C2x...@eskimo.com>, Steve Summit <s...@eskimo.com> wrote:
>The fact is that it "works" *for you*, under *this one compiler*.
>How sure are you that it will work everywhere?

I suspect that he is not even sure that it works under that one compiler.
The only way to be sure is if well defined behavior is provided as a documented
extension, or if we can reverse engineer the implementation. He is probably
just guessing based on empirical tests which is a bad thing to do even if all
you are doing is programming for one particular C implementation. For all we
know, different results may be obtainable by simply fiddling with that one
implementation's parameters.

Hector Echavarria

unread,
Apr 8, 1997, 3:00:00 AM4/8/97
to

> George C. Lindauer wrote:
>
> a = b++ + b;

I think that the proper way to do that is:
b += b++;

Hector Echavarria

Dann Corbit

unread,
Apr 9, 1997, 3:00:00 AM4/9/97
to

Hector Echavarria <hec...@aacr.net> wrote in article
<01bc4468$6105f840$716f...@198.240.111.113>...

> > George C. Lindauer wrote:
> >
> > a = b++ + b;
>
> I think that the proper way to do that is:
> b += b++;
I think Scott Nudds might fly out of your nose... Does that make it true?
When you said, "I think..." that implied you were not sure of your answer.
And you were correct in second guessing yourself, because you replaced one
boo-boo with another. When trying to help someone out, please be sure of
your facts. Suppose that the person who asked this question was writing an
embedded program to control your grandmother's pacemaker. You would want
the program to be accurate. You don't know what the original poster wants
it for. Pretend that he writes embedded systems that control pacemakers.
If you want the new contents of a to be "2*b + 1", then write:
a = b+b+1;
or

a = 2*b + 1;

or any of the myriads of other forms that are clear and correct.

Here is what lint said:
--- Module: oops.c
_
b += b++;
oops.c(4) : Warning 564: variable b depends on order of evaluation
---

about this:
C:\tmp\sl>type oops.c
int main()
{
int b = 5;
b += b++;

return 0;
}


Danette & Murray Root

unread,
Apr 9, 1997, 3:00:00 AM4/9/97
to

On 8 Apr 1997 23:32:13 GMT, k...@vision.crest.nt.com (Kaz Kylheku) wrote in
comp.lang.c:

=> In article <E8C2x...@eskimo.com>, Steve Summit <s...@eskimo.com> wrote:
=> >The fact is that it "works" *for you*, under *this one compiler*.
=> >How sure are you that it will work everywhere?

=> I suspect that he is not even sure that it works under that one compiler.
=> The only way to be sure is if well defined behavior is provided as a documented
=> extension, or if we can reverse engineer the implementation. He is probably
=> just guessing based on empirical tests which is a bad thing to do even if all
=> you are doing is programming for one particular C implementation. For all we
=> know, different results may be obtainable by simply fiddling with that one
=> implementation's parameters.

Heck, all you have to do is hardcode specific numbers under MSVC++. It
optimizes away any arithmetic (by whatever rules MS has decided upon) and
substitutes the result. Voila! Predictable results. (This bit me once, when I
was thinking I could figure out the 'undefined behaviour' of a similar
expression - the tests worked fine with i = 1. The function failed
impressively when i = <user input>.)


<><><><><><><><><><><><><><><><><><><><>

Wizard's First Rule:
People are stupid.
Wizard's Second Rule:
Never depend on the first rule.

<><><><><><><><><><><><><><><><><><><><>


Cookie Monster

unread,
Apr 9, 1997, 3:00:00 AM4/9/97
to

Peter Seebach wrote ...

> I can just see you explaining that the bridge worked fine when you
> drove your Geo Metro across it.

Peter must be in the USA. For "Geo Metro" read "Suzuki Swift" in the UK.
That's one _small_ car (even smaller than the old Austin "Metro"). Do they
call them anything else in other countries?


Kaz Kylheku

unread,
Apr 9, 1997, 3:00:00 AM4/9/97
to

In article <01bc4468$6105f840$716f...@198.240.111.113>,

Hector Echavarria <hec...@aacr.net> wrote:
> > George C. Lindauer wrote:
> >
> > a = b++ + b;
>
>I think that the proper way to do that is:
>b += b++;
>
> Hector Echavarria

However, it is not the most efficient way, which would be:

void main(){*((char*)0)='+'+'+'/'-'-'-';}

Christian Bau

unread,
Apr 9, 1997, 3:00:00 AM4/9/97
to

> Stephan Wilms wrote:


> >
> > Brian Ross wrote:
> > >
> > > George C. Lindauer wrote:
> > > >
> > > > a = b++ + b;
> > >

> > > My guess is that this should expand to:
> > >
> > > a = b + b;
> > > b++;
> > >
> > > if it had been a = ++b + b, it would be:
> > >
> > > b++;
> > > a = b + b;
> > >

> > > --
> > > Brian Ross (br...@engsoc.carleton.ca)
> >
> > WRONG on both occasions. Please read the other replies in this thread
> > AND
> > you might want to scan the c.l.c FAQ for "sequence points".
>

> Thats funny.. I tried it on my compiler (BC++3.1) and funny
> enough it does exactly what I said it would do.
>

> so does:
>
> i = 0;


> a = i++ + i++;
> a gets assigned 0;
>

> i = 0;


> a = ++i + i++;
> a gets assigned 2;
>

> i = 0;
> a = ++i + ++i;
> a gets assigned 4;
>

> I see nothing unexpected about this. I don't care whether is
> 'non standard' or whatever, the fact is that it works.

I am quite sure that you will get severely flamed because this code does
cause "undefined behavior" according to the C standard and you say it is
ok to use it. My own attitude s that code that causes undefined behavior
is not bad through that fact alone, as long as the programmer knows what
he is doing. This is not the case here. There are things that are
undefined in C, but work predictably on a certain machine+compiler
combination. This is not the case here. Whatever results you get, it
happens by poor chance.

The results that you get are completely unpredictable. It might be that if
you have a very very simple compiler, then you might be able to predict
the results (not in the sense that the compiler gives any guarantees, but
in the sense that you can guess and be right in more than 90% of the
cases). I dont think BC++3.1 falls into this category, not with the
results you quoted.

On any optimising compiler it is completely unpredictable for the
programmer (and maybe even for the programmer who wrote the compiler) in
which order the operands of (expr1) + (expr2) are evaluated. The compiler
looks for optimisations, and rearranges your code in order to find better
code, and in a situation where the order of operands doesnt matter, it is
completely unpredictable which one is evaluated first.

There is a good chance the result is different in BC++3.2. If your
compiler lets you choose optimisation levels, that will probably make a
difference. If your code is acceptable both to a C compiler and a C++
compiler (say BC3.1 and BC++3.1), the results could be different. It will
make a difference if this is the first, second or third assignment in the
function. It will make a difference whether you write i = 0 or i=x and x
happened to be zero. I know one Windows compiler where it can depend on
how much memory your computer has when you compile.

-- For email responses, please remove the last emm from my address.
-- For spams, please send them to whereever...@but.not.here

E. Young

unread,
Apr 9, 1997, 3:00:00 AM4/9/97
to

k...@vision.crest.nt.com (Kaz Kylheku) writes:

> Hector Echavarria <hec...@aacr.net> wrote:
> > > George C. Lindauer wrote:
> > > a = b++ + b;
> >
> >I think that the proper way to do that is:
> >b += b++;
> >
> However, it is not the most efficient way, which would be:
>
> void main(){*((char*)0)='+'+'+'/'-'-'-';}
>

IMHO, this is a needlessly verbose way of coredumping. Wouldn't

int main(){int x=*(int *)0;}

do just as well? Granted, yours is prettier :)

-Edwin

Kaz Kylheku

unread,
Apr 9, 1997, 3:00:00 AM4/9/97
to

In article <ptc3et0...@hammer.thor.cam.ac.uk>,
E. Young <ey...@thor.cam.ac.uk> wrote:

>> However, it is not the most efficient way, which would be:
>>
>> void main(){*((char*)0)='+'+'+'/'-'-'-';}
>>
>
>IMHO, this is a needlessly verbose way of coredumping. Wouldn't
>
>int main(){int x=*(int *)0;}
>
>do just as well? Granted, yours is prettier :)

Yours may dump core faster (on those systems that feature core dumps)
but mine invokes undefined behavior sooner (void main). On a few rare
platforms, execution won't even reach the body of main and some
compilers will refuse it altogether, or at least produce a diagnostic.

The null pointer dereference and division by zero were just decoys. :)

Jens Schweikhardt

unread,
Apr 9, 1997, 3:00:00 AM4/9/97
to

In article <01bc4468$6105f840$716f...@198.240.111.113> "Hector Echavarria" <hec...@aacr.net> writes:
# > George C. Lindauer wrote:
# >
# > a = b++ + b;
#
# I think that the proper way to do that is:
# b += b++;

I think that the proper way to avoid this bullshit is reading the FAQ.

# Hector Echavarria

Jens Schweikhardt

unread,
Apr 9, 1997, 3:00:00 AM4/9/97
to

In article <ptc3et0...@hammer.thor.cam.ac.uk> ey...@thor.cam.ac.uk (E. Young) writes:
# k...@vision.crest.nt.com (Kaz Kylheku) writes:

# > Hector Echavarria <hec...@aacr.net> wrote:
# > > > George C. Lindauer wrote:
# > > > a = b++ + b;
# > >
# > >I think that the proper way to do that is:
# > >b += b++;
# > >
# > However, it is not the most efficient way, which would be:
# >
# > void main(){*((char*)0)='+'+'+'/'-'-'-';}
# >
#
# IMHO, this is a needlessly verbose way of coredumping. Wouldn't
#
# int main(){int x=*(int *)0;}
#
# do just as well? Granted, yours is prettier :)
#
# -Edwin


I'd like to jump in on this one and suggest a new contest:

What's the shortest C program likely to dump core?
(on systems where core dumps are defined by ISO 0401:42)

My entry, probably with enough room for improvement:

main(){*errno/=0;}

ObC: How many instances of undefined behaviour are in this line?
What's the undefinedness per source character (upsc) ratio?
Is this value rounded up, down, towards zero or not at all?
How many Nuddses does it take to screw in a light bulb?
Answer: No amount of Nuddses will do, as he will confuse
floor and ceiling and try to locate that socket in the carpet.

E. Young

unread,
Apr 9, 1997, 3:00:00 AM4/9/97
to

schw...@rubin.noc.dfn.de (Jens Schweikhardt) writes:

> What's the shortest C program likely to dump core?
> (on systems where core dumps are defined by ISO 0401:42)
>
> My entry, probably with enough room for improvement:
>
> main(){*errno/=0;}

how about

main(){puts(0);}

Is the lack of a defn for puts() a good or bad thing in this
context? ;)



> How many Nuddses does it take to screw in a light bulb?

You're not screwing in that lightbulb efficiently enough! You
need a portable java native-code optimizing-like-shit nested-
comment-supporting no-typedefs Nuddsoft (TM) lightbulb screwer!

> Answer: No amount of Nuddses will do, as he will confuse
> floor and ceiling and try to locate that socket in the carpet.

#include <carpet/socket.h> ?

-Edwin

Jos A. Horsmeier

unread,
Apr 9, 1997, 3:00:00 AM4/9/97
to

Jens Schweikhardt <schw...@rubin.noc.dfn.de> wrote in article
<5ig1iv$jo3$1...@news.belwue.de>...

| I'd like to jump in on this one and suggest a new contest:
|

| What's the shortest C program likely to dump core?
| (on systems where core dumps are defined by ISO 0401:42)
|
| My entry, probably with enough room for improvement:
|
| main(){*errno/=0;}
|

| ObC: How many instances of undefined behaviour are in this line?
| What's the undefinedness per source character (upsc) ratio?
| Is this value rounded up, down, towards zero or not at all?

| How many Nuddses does it take to screw in a light bulb?

| Answer: No amount of Nuddses will do, as he will confuse
| floor and ceiling and try to locate that socket in the carpet.

K&R1 C (by means of good ol' cc and ld) gently allowed one to dump
core as follows:

main;

Sigh, those were the days ... ;-)

Jos aka j...@and.nl


Dan Evens

unread,
Apr 9, 1997, 3:00:00 AM4/9/97
to

Jens Schweikhardt wrote:
> Answer: No amount of Nuddses will do, as he will confuse
> floor and ceiling and try to locate that socket in the carpet.

Depending on the location of the socket is risky programming
because the ANSI standard does not specify it. :)

--
Standard disclaimers apply.
I don't buy from people who advertise by e-mail.
I don't buy from their ISPs.
Dan Evens

Tim Behrendsen

unread,
Apr 9, 1997, 3:00:00 AM4/9/97
to

Jens Schweikhardt <schw...@rubin.noc.dfn.de> wrote in article
> I'd like to jump in on this one and suggest a new contest:
>
> What's the shortest C program likely to dump core?
> (on systems where core dumps are defined by ISO 0401:42)
>
> My entry, probably with enough room for improvement:
>
> main(){*errno/=0;}

I don't think yours will work on the average, because errno
is undeclared.

This is one longer, but will probably work...

main(){*(int*)0=0;}

This might work, but didn't under AIX, at least...

main(){*(int*)0;}

However, this did! (alignment error, probably)

main(){*(int*)1;}

Shortest divide by zero fault?

main(){int a=0;a/a;}

--
==========================================================================
| Tim Behrendsen (t...@a-sis.com) | http://www.cerfnet.com/~timb |
| "Judge all, and be prepared to be judged by all." |
==========================================================================

James McIninch

unread,
Apr 9, 1997, 3:00:00 AM4/9/97
to

How about:

int main=0;

--
James McIninch
School of Biology, Georgia Tech, Atlanta, GA 30332-0230
ja...@amber.biology.gatech.edu

Billy Chambless

unread,
Apr 9, 1997, 3:00:00 AM4/9/97
to

In article <5ig1iv$jo3$1...@news.belwue.de>, schw...@rubin.noc.dfn.de (Jens Schweikhardt) writes:


|> main(){*errno/=0;}

|> ObC: How many instances of undefined behaviour are in this line?
|> What's the undefinedness per source character (upsc) ratio?

What a lovely metric to use? Can I borrow that for the coding standard
I'm working on? ;)

|> Is this value rounded up, down, towards zero or not at all?

Yes.

|> How many Nuddses does it take to screw in a light bulb?

|> Answer: No amount of Nuddses will do, as he will confuse
|> floor and ceiling and try to locate that socket in the carpet.

Wrong. Nudds will whine about how lightbulbs optimise like shit,
insist that everyone should be using Portable Light Source (which hasn't
been invented yet), then sit in the dark and whimper.

Lightbulb pushers will say anything to defend their sad little religion.

--
* "We all agree on the necessity of compromise. We just can't agree on
* when it's necessary to compromise."
* --Larry Wall in <1991Nov13.1...@netlabs.com>


Tim Behrendsen

unread,
Apr 9, 1997, 3:00:00 AM4/9/97
to

Tim Behrendsen <t...@a-sis.com> wrote in article <01bc44f2$a53639a0$87ee6fce@timpent.a-

> Shortest divide by zero fault?
>
> main(){int a=0;a/a;}

Actually, this is shorter..

int a;main(){a/a;}

Dann Corbit

unread,
Apr 9, 1997, 3:00:00 AM4/9/97
to

Here's my favorite:
main { main(); };

It may take a while on a machine with virtual memory, but the spectacular
results will be worth the wait.


Peter Seebach

unread,
Apr 9, 1997, 3:00:00 AM4/9/97
to

In article <5ig1iv$jo3$1...@news.belwue.de>,

Jens Schweikhardt <schw...@rubin.noc.dfn.de> wrote:
>I'd like to jump in on this one and suggest a new contest:

> What's the shortest C program likely to dump core?
> (on systems where core dumps are defined by ISO 0401:42)

Is that a real standard?

>My entry, probably with enough room for improvement:

> main(){*errno/=0;}

My current best effort:
main(){main();}

>ObC: How many instances of undefined behaviour are in this line?

A curiousity: Mine does not invoke undefined behavior in any obvious way.

It may merely loop forever on an implementation which performs tail recursion
elimination.


-s
--
Copyright 1997 Peter Seebach - seebs at solon.com - C/Unix Wizard
I am not actually gla...@nancynet.com but junk mail is accepted there.
The *other* C FAQ, the hacker FAQ, et al. http://www.solon.com/~seebs
Unsolicited email (junk mail and ads) is unwelcome, and will be billed for.

Lawrence Kirby

unread,
Apr 9, 1997, 3:00:00 AM4/9/97
to

In article <christian.bau-0...@christian-mac.isltd.insignia.com>
christ...@isltd.insignia.comm "Christian Bau" writes:

>I am quite sure that you will get severely flamed because this code does
>cause "undefined behavior" according to the C standard and you say it is
>ok to use it. My own attitude s that code that causes undefined behavior
>is not bad through that fact alone, as long as the programmer knows what
>he is doing.

Code that causes undefined behaviour is bad if there is no good reason for
it, i.e. if there's a well-defined version of the code that isn't overly
complex or inefficient or slow. That's basically what the void main()
argument is all about, it is quite simply bad programming practice because
it doesn't buy you anything in return for dropping the standards, even
on a platform whene it is "known" to work.

There are many cases of undefined behavior that take the form of useful
(or even essential) platform related extensions. A programmer will generally
make use of these extensions frequently in practice and there is nothing
wrong with that (although it is a good idea to go for the more standard
solution where there is a choice).

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


Alun Da Penguin Jones

unread,
Apr 9, 1997, 3:00:00 AM4/9/97
to

Further up the screen t...@a-sis.com (Tim Behrendsen) wrote:
> > Shortest divide by zero fault?
> >
> > main(){int a=0;a/a;}
>
> Actually, this is shorter..
>
> int a;main(){a/a;}

If we're going to allow main() to default to an int function, can't we
allow "a" to default to an integer:

a;main(){a/a;}

Mind you, when I compiled this, it didn't cause a divide by zero fault
and, looking at the code generated, it looks like gcc had optimized the
division away completely!

Cheers,
Alun.

--
/P{def}def/E{curveto}P/N{moveto}P/G{lineto}P/U{setgray}P/I{fill}P/n{stroke}P
(2V<;;F<K5F5=8<5K-/3/6//C3?/367/W/O6/-0+3'//K3?/3:[0[/WB>>H<W6/;/C///1W'T1Q)
6 6 scale .2 setlinewidth 1 .7 0 setrgbcolor{}forall N G G I 0 U N E E E E E
I 1 U N E E E gsave I grestore 0 U n .3 U N E E n 1 0 360 arc I showpage%auj

Jens Schweikhardt

unread,
Apr 9, 1997, 3:00:00 AM4/9/97
to

In article <5iglaj$2...@solutions.solon.com> se...@solon.com writes:
# In article <5ig1iv$jo3$1...@news.belwue.de>,
# Jens Schweikhardt <schw...@rubin.noc.dfn.de> wrote:
# >I'd like to jump in on this one and suggest a new contest:
#
# > What's the shortest C program likely to dump core?
# > (on systems where core dumps are defined by ISO 0401:42)
#
# Is that a real standard?

Umm, that would be surprising... I know it comes too late,
0401 is April 1 and 42 is, uhm, the arbitrary prime? :-)

# >My entry, probably with enough room for improvement:
#
# > main(){*errno/=0;}

My entry unfortunately does not compile on a number of systems.
So I disqualified it.

# My current best effort:
# main(){main();}

Hey, I like that one! I give it the 'Worst Abuse of the VM Sytem Award'.

# >ObC: How many instances of undefined behaviour are in this line?
#
# A curiousity: Mine does not invoke undefined behavior in any obvious way.

I havn't spotted it yet. Does it exceed some limit, like the number
of function calls nesting at runtime?

# It may merely loop forever on an implementation which performs tail recursion
# elimination.

I can live with that... :-)
Yo, folks. Isn't that much more interesting than hopeless debate threads?

# -s
# --
# Copyright 1997 Peter Seebach - seebs at solon.com - C/Unix Wizard
# I am not actually gla...@nancynet.com but junk mail is accepted there.
# The *other* C FAQ, the hacker FAQ, et al. http://www.solon.com/~seebs
# Unsolicited email (junk mail and ads) is unwelcome, and will be billed for.

Gabriel Cain

unread,
Apr 9, 1997, 3:00:00 AM4/9/97
to

My submition:

main(){int a=1/0;}

--
PROGRAM (pro'-gram) [n] A magic spell cast over a .----. . - .
computer allowing it to turn one's input into error |C>_.|.:'.:. .
messages. [vi] To engage in a pastime similar to _|____|_ `:. O_/
banging one's head against a wall, but, with fewer | --| \/M
opportunities for reward. `-######-'a _/ \_


Dik T. Winter

unread,
Apr 9, 1997, 3:00:00 AM4/9/97
to

In article <860610...@genesis.demon.co.uk> fr...@genesis.demon.co.uk writes:
> There are many cases of undefined behavior that take the form of useful
> (or even essential) platform related extensions. A programmer will generally
> make use of these extensions frequently in practice and there is nothing
> wrong with that (although it is a good idea to go for the more standard
> solution where there is a choice).

And it is also a good idea to document such uses of undefined behavior!
There are sources around that are littered with the use of undefined
behavior without any documentation of such (all the world is a Vax).
--
dik t. winter, cwi, kruislaan 413, 1098 sj amsterdam, nederland, +31205924131
home: bovenover 215, 1025 jn amsterdam, nederland; http://www.cwi.nl/~dik/

Tim Behrendsen

unread,
Apr 9, 1997, 3:00:00 AM4/9/97
to

James McIninch <ja...@amber.biology.gatech.edu> wrote in article
<5igahd$k...@smash.gatech.edu>...
> How about:
>
> int main=0;

Nah, that might just get an undefined external function 'main'
if the linker is semi-smart.

Stephan Wilms

unread,
Apr 9, 1997, 3:00:00 AM4/9/97
to

Brian Ross wrote:
>
> Stephan Wilms wrote:
> >
> > Brian Ross wrote:
> > >
> > > George C. Lindauer wrote:
> > > >
> > > > a = b++ + b;
> > >
> > > My guess is that this should expand to:
> > >
> > > a = b + b;
> > > b++;
> > >
> > > if it had been a = ++b + b, it would be:
> > >
> > > b++;
> > > a = b + b;
> > >
> > > --
> > > Brian Ross (br...@engsoc.carleton.ca)
> >
> > WRONG on both occasions. Please read the other replies in this thread
> > AND
> > you might want to scan the c.l.c FAQ for "sequence points".
>
> Thats funny.. I tried it on my compiler (BC++3.1) and funny
> enough it does exactly what I said it would do.
>
[snip snip snip]

>
> I see nothing unexpected about this. I don't care whether is
> 'non standard' or whatever, the fact is that it works.

Again: if you don't believe, refer to other sources of information, like
the FAQ or a good book AND read the other replies in the thread.

It is not guarantied to work (because it violates the C language
definition) but it might just work on your compiler for this occasion.
It is likely produce different results on other compilers because it is
simply and utterly WRONG: it's NOT legal C code.

Stephan

Jens Schweikhardt

unread,
Apr 9, 1997, 3:00:00 AM4/9/97
to

In article <01bc450b$0d741740$ca61...@DCorbit.solutionsiq.com> "Dann Corbit" <dco...@solutionsiq.com> writes:
# Here's my favorite:
# main { main(); };
#
# It may take a while on a machine with virtual memory, but the spectacular
# results will be worth the wait.


Bzzzt! Thanks for playing.
I give it the 'Least likely to compile Award' :-)


Regards,

Rich Miller

unread,
Apr 9, 1997, 3:00:00 AM4/9/97
to

In article <christian.bau-0...@christian-mac.isltd.insignia.com>,
Christian Bau <christ...@isltd.insignia.comm> wrote:

> ... My own attitude is that code that causes undefined behavior


> is not bad through that fact alone, as long as the programmer knows what
> he is doing.

This is an astounding statement! -- or at least it should be. Unfortunately,
many programmers seem to share a similar attitude, and we as a community
are most definitely impacted by the buggy code that seems the inevitable
result of such lack of concern for "doing the right thing".

What is perhaps most concerning about the current debate (on the value of
'a' after evaluation of "i = 0; a = i++ + i++;") is that avoiding the
problem entirely is so easy! In a similar vein, why fight so hard
against declaring "int main()" (not void!)? Yet these debates seem
interminable.

If a programmer isn't willing to make the almost negligible effort to
get the easy things right, why should anyone expect them to get the
hard stuff right?

-- Rich Miller

Craig Franck

unread,
Apr 10, 1997, 3:00:00 AM4/10/97
to

"Tim Behrendsen" <t...@a-sis.com> wrote:
>Tim Behrendsen <t...@a-sis.com> wrote in article <01bc44f2$a53639a0$87ee6fce@timpent.a-
>> Shortest divide by zero fault?
>>
>> main(){int a=0;a/a;}
>
>Actually, this is shorter..
>
> int a;main(){a/a;}

Talk about *bloated* code!

main(){1/0;}

--
Craig
clfr...@worldnet.att.net
Manchester, NH
Man is the only animal for whom his own existence is
a problem which he has to solve. -- Erich Fromm

Danette & Murray Root

unread,
Apr 10, 1997, 3:00:00 AM4/10/97
to

On 9 Apr 1997 12:57:39 -0500, se...@solutions.solon.com (Peter Seebach) wrote
in comp.lang.c:

=> My current best effort:
=> main(){main();}

=> >ObC: How many instances of undefined behaviour are in this line?

=> A curiousity: Mine does not invoke undefined behavior in any obvious way.

=> It may merely loop forever on an implementation which performs tail recursion
=> elimination.

Yup. On MSVC++ 5.0 it gets compiled to a one-instruction (after the prolog
stuff) program.

$L61:
jmp SHORT $L61

It runs until I get tired of it.


<><><><><><><><><><><><><><><><><><><><>

Wizard's First Rule:
People are stupid.
Wizard's Second Rule:
Never depend on the first rule.

<><><><><><><><><><><><><><><><><><><><>


Andy Isaacson

unread,
Apr 10, 1997, 3:00:00 AM4/10/97
to

The USENET cabal made E. Young <ey...@thor.cam.ac.uk> say:
>k...@vision.crest.nt.com (Kaz Kylheku) writes:

>> Hector Echavarria <hec...@aacr.net> wrote:
>> > > George C. Lindauer wrote:
>> > > a = b++ + b;
>> >
>> >I think that the proper way to do that is:
>> >b += b++;

>> >
>> However, it is not the most efficient way, which would be:
>>
>> void main(){*((char*)0)='+'+'+'/'-'-'-';}
>>
>
>IMHO, this is a needlessly verbose way of coredumping. Wouldn't
>
>int main(){int x=*(int *)0;}

On many (SysV) platforms which feature core dumps (in the words of another
poster), page 0 is readable (always returns 0). So, on a significant
fraction of platforms, this program will not even do what it is documented
to do (ie, core dump.)

>do just as well? Granted, yours is prettier :)

-andy "main(){*(int*)5=0;}"
--
Andy Isaacson <adis...@mtu.edu> -- conserve bandwidth, use one line sigs.

E. Young

unread,
Apr 10, 1997, 3:00:00 AM4/10/97
to

schw...@rubin.noc.dfn.de (Jens Schweikhardt) writes:
> "Dann Corbit" writes:
> # main { main(); };

> Bzzzt! Thanks for playing.
> I give it the 'Least likely to compile Award' :-)

Eh? I think this is the most reliable one I've seen so far.

% cat >weird.c
main(){main();}
^D
% gcc weird.c -ansi -pedantic -Wall
weird.c:1: warning: return-type defaults to `int'
weird.c: In function `main':
weird.c:1: warning: control reaches end of non-void function
[ Oh no it doesn't ;) ]

% a.out
Segmentation fault (core dumped)

Seriously, I can't see anything wrong with it... And it's shorter
than my version, drat it.

-Edwin

Jens Schweikhardt

unread,
Apr 10, 1997, 3:00:00 AM4/10/97
to

In article <ptc4tdf...@hammer.thor.cam.ac.uk> ey...@thor.cam.ac.uk (E. Young) writes:
# schw...@rubin.noc.dfn.de (Jens Schweikhardt) writes:
# > "Dann Corbit" writes:
# > # main { main(); };
#
# > Bzzzt! Thanks for playing.
# > I give it the 'Least likely to compile Award' :-)
#
# Eh? I think this is the most reliable one I've seen so far.
#
# % cat >weird.c
# main(){main();}
# ^D
# % gcc weird.c -ansi -pedantic -Wall
# weird.c:1: warning: return-type defaults to `int'
# weird.c: In function `main':
# weird.c:1: warning: control reaches end of non-void function
# [ Oh no it doesn't ;) ]
#
# % a.out
# Segmentation fault (core dumped)
#
# Seriously, I can't see anything wrong with it...

As they say to Dan: You need new glasses :-)

Dann Corbitt: main { main(); };
Your's : main(){main();}

There are at least two problems here...

# And it's shorter than my version, drat it.
#
# -Edwin

E. Young

unread,
Apr 10, 1997, 3:00:00 AM4/10/97
to

schw...@rubin.noc.dfn.de (Jens Schweikhardt) writes:

> As they say to Dan: You need new glasses :-)
>
> Dann Corbitt: main { main(); };
> Your's : main(){main();}
>
> There are at least two problems here...

Doh! There's me thinking people usually write code that
actually makes sense. Must have confused this with Seebach's
version.

-Edwin

Tim Behrendsen

unread,
Apr 10, 1997, 3:00:00 AM4/10/97
to

Craig Franck <clfr...@worldnet.att.net> wrote in article
<5ihd57$s...@mtinsc04.worldnet.att.net>...

> "Tim Behrendsen" <t...@a-sis.com> wrote:
> >Tim Behrendsen <t...@a-sis.com> wrote in article <01bc44f2$a53639a0$87ee6fce@timpent.a-
> >> Shortest divide by zero fault?
> >>
> >> main(){int a=0;a/a;}
> >
> >Actually, this is shorter..
> >
> > int a;main(){a/a;}
>
> Talk about *bloated* code!
>
> main(){1/0;}

Not reliable! My compiler rejects the constant. This should
be a portable core dump. :-)

Tim Behrendsen

unread,
Apr 10, 1997, 3:00:00 AM4/10/97
to

Peter Seebach <se...@solutions.solon.com> wrote in article
<5iglaj$2...@solutions.solon.com>...

>
> My current best effort:
> main(){main();}

Does that give you a core dump? I just run out of memory, and
the O/S kills it.

niteh...@aol.com

unread,
Apr 10, 1997, 3:00:00 AM4/10/97
to

Im Artikel <01bc44f2$a53639a0$87ee...@timpent.a-sis.com>, "Tim Behrendsen" <t...@a-sis.com> schreibt:

>Shortest divide by zero fault?
>
> main(){int a=0;a/a;}

what about : main(){1/0;} ?


Matthias
<NiteH...@aol.com>

*Artificial intelligence is better than natural stupidity =)


Chris Engebretson

unread,
Apr 10, 1997, 3:00:00 AM4/10/97
to

In article <5igpbc$d...@ratty.wolfe.net>, rmi...@WOLFENET.COM (Rich Miller) writes:

|> In article <christian.bau-0...@christian-mac.isltd.insignia.com>,
|> Christian Bau <christ...@isltd.insignia.comm> wrote:
|>
|> > ... My own attitude is that code that causes undefined behavior
|> > is not bad through that fact alone, as long as the programmer knows what
|> > he is doing.
|>
|> This is an astounding statement! -- or at least it should be. Unfortunately,
|> many programmers seem to share a similar attitude, and we as a community
|> are most definitely impacted by the buggy code that seems the inevitable
|> result of such lack of concern for "doing the right thing".

Indeed. But this is not the point that Christian was trying to make.
There are times when invoking undefined behavior *is* the right thing
to do. Consider the following three lines of code:

#include <stdio.h>
#include <socket.h>
#include <curses.h>

These three lines of code invoke undefined behavior twice, both stemming
(obviously) from the #inclusion of a non-standard header. Now, while it
is true that this code (and code like it) has no value or relevance to
comp.lang.c, it's a fair guess that the author of this code knows what
he is doing by #including these headers, even though the behavior that
results is not defined by the C standard.

Now, on the other hand, given the expression statement

i = a + (++i + ++a);

it's *not* clear that the author knows what he's doing. Like the above
example, what this code *does* is not defined by the standard. However,
unlike the above example, which is given a well-known meaning by several
popular implementations, this example is dangerous, and just silly.

Thus, one has to differentiate between "good" undefined behavior and
"bad" undefined behavior; although these terms are egregiously informal,
we might be able to provide some sort of working definitions for them:

Good Undefined Behavior - Program constructs or elements whose behavior
is not defined by the C standard, but are not expressly disallowed
and have been given meaning by current implementations and practice.
Example as above: #including a nonstandard header.

Bad Undefined Behavior - Everything else; that is, program constructs
that are improbable, unwise, or just plain ridiculous. Example as
above: modifying the value of an object twice without any
intervening sequence points.

I wouldn't look for these definitions anywhere in C9X, though. :-)

|> What is perhaps most concerning about the current debate (on the value of
|> 'a' after evaluation of "i = 0; a = i++ + i++;") is that avoiding the
|> problem entirely is so easy!

Correct. This is Bad Undefined Behavior.

|> If a programmer isn't willing to make the almost negligible effort to
|> get the easy things right, why should anyone expect them to get the
|> hard stuff right?

Correct again. C programmers ought to obtain a good working knowledge of
the base language before they begin making widespread use of Good
Undefined Behavior. In this way, they know that the tools that they're
using are extensions provided by their implementation, and are aware of
the fact that such tools (or parallels to them) may not exist universally.

Regards,

--
Chris Engebretson, USGS/NMD U|S E-mail: enge...@usgs.gov
EROS Data Center -+- Telephone: (605) 594-6829
Sioux Falls, SD 57198 G|S Fax: (605) 594-6490
My opinions given here are not necessarily those of the USGS.

Dik T. Winter

unread,
Apr 10, 1997, 3:00:00 AM4/10/97
to

In article <ptc4tdf...@hammer.thor.cam.ac.uk> ey...@thor.cam.ac.uk (E. Young) writes:
> Eh? I think this is the most reliable one I've seen so far.
>
> % cat >weird.c
> main(){main();}
^^
With these it does compile indeed, but does it dump core?

ksh: cat >foo.c
main(){main();}
ksh: cc foo.c
ksh: a.out
ALERT: a.out [20290] - out of logical swap space during stack growth - see swap(1M)
ALERT: a.out [20290] - out of logical swap space during stack growth - see swap(1M)
WARNING: Process [a.out] pid 20290 killed: not enough memory to grow stack
Killed
ksh: ls core
Cannot access core: No such file or directory
ksh:

Dik T. Winter

unread,
Apr 10, 1997, 3:00:00 AM4/10/97
to

In article <5ihd57$s...@mtinsc04.worldnet.att.net> Craig Franck <clfr...@worldnet.att.net> writes:
> Talk about *bloated* code!
>
> main(){1/0;}

But does it dump core?

ksh: cat >foo.c
main(){1/0;}
ksh: cc foo.c
cfe: Warning 697: foo.c, line 1: Division by zero.
main(){1/0;}
---------^
ksh: a.out

Kaz Kylheku

unread,
Apr 10, 1997, 3:00:00 AM4/10/97
to

In article <5igpbc$d...@ratty.wolfe.net>,

Rich Miller <rmi...@WOLFENET.COM> wrote:
>In article <christian.bau-0...@christian-mac.isltd.insignia.com>,
>Christian Bau <christ...@isltd.insignia.comm> wrote:
>
>> ... My own attitude is that code that causes undefined behavior
>> is not bad through that fact alone, as long as the programmer knows what
>> he is doing.
>
>This is an astounding statement! -- or at least it should be. Unfortunately,
>many programmers seem to share a similar attitude, and we as a community
>are most definitely impacted by the buggy code that seems the inevitable
>result of such lack of concern for "doing the right thing".

Buggy code and code that causes undefined behavior are two differen things.
I am in agreement with Christian Bau here.

Undefined behavior is not only an area which covers incorrect programming
constructs or behavior arising from incorrect data. It is also an area for
potential extensions to the language.

Any time you include a non standard C header, or use a non standard function,
you are invoking undefined behavior.

Undefined and implementation defined behaviors also allow C implementations
to be used as ``high level assemblers'' for writing something that is
non-portable, but faster than what would be possible with strictly conforming
code.

The key is ``as long as the programmer knows what he or she is doing''.

Dann Corbit

unread,
Apr 10, 1997, 3:00:00 AM4/10/97
to

Jens Schweikhardt <schw...@rubin.noc.dfn.de> wrote in article
<5iia0n$jft$1...@news.belwue.de>...
[snip]

> As they say to Dan: You need new glasses :-)
>
> Dann Corbitt: main { main(); };
> Your's : main(){main();}
>
> There are at least two problems here...
Quite so. I was afraid even to compile it.

Dann Corbit

unread,
Apr 10, 1997, 3:00:00 AM4/10/97
to

In article <E8FG6...@cwi.nl>, d...@cwi.nl says...

>
>In article <ptc4tdf...@hammer.thor.cam.ac.uk> ey...@thor.cam.ac.uk (E. Youn
>g) writes:
> > Eh? I think this is the most reliable one I've seen so far.
> >
> > % cat >weird.c
> > main(){main();}
> ^^
>With these it does compile indeed, but does it dump core?
>
>ksh: cat >foo.c

>main(){main();}
>ksh: cc foo.c
>ksh: a.out
>ALERT: a.out [20290] - out of logical swap space during stack growth - see swap(
>1M)
>ALERT: a.out [20290] - out of logical swap space during stack growth - see swap(
>1M)
>WARNING: Process [a.out] pid 20290 killed: not enough memory to grow stack
>Killed
>ksh: ls core
>Cannot access core: No such file or directory
>ksh:
>--
>dik t. winter, cwi, kruislaan 413, 1098 sj amsterdam, nederland, +31205924131
>home: bovenover 215, 1025 jn amsterdam, nederland; http://www.cwi.nl/~dik/
Actually core dumps are a UNIX phenomena.

I get an illegal operation: invalid page fault or stack fault on the ones
that do compile and run. Here is the program summary, and the results on
my architecture. The ones with no comments do recieve a register listing:

#ifdef M1ST
a;main(){a/a;} /* Does nothing */
#endif
#ifdef M2ND
int a;main(){a/a;} /* Does nothing */
#endif
#ifdef M3RD
int main(){int x=*(int *)0;} /* With optimization on, does nothing */
#endif
#ifdef M4TH
int main=0;
#endif
#ifdef M5TH
main { main(); }; /* Fails to compile [my entry -- oops] */
/*
oops.c
oops.c(14) : error C2054: expected '(' to follow 'main'
*/
#endif
#ifdef M6TH
main(){*(int*)0;} /* Does nothing */
#endif
#ifdef M7TH
main(){*(int*)0=0;}
#endif
#ifdef M8TH
main(){*(int*)1;} /* Does nothing */
#endif
#ifdef M9TH
main(){*errno/=0;} /* Fails to compile */
/*
oops.c
oops.c(30) : error C2065: 'errno' : undeclared identifier
oops.c(30) : error C2100: illegal indirection
*/
#endif
#ifdef M10TH
main(){1/0;} /* Fails to compile */
/*
oops.c
oops.c(38) : error C2124: divide or mod by zero
*/
#endif
#ifdef M11TH
main(){int a=0;a/a;} /* Does nothing */
#endif
#ifdef M12TH
main(){int a=1/0;} /* Fails to compile */
/*
oops.c
oops.c(48) : error C2124: divide or mod by zero
*/
#endif
#ifdef M13TH
main(){main();}
#endif
#ifdef M14TH
main(){puts(0);}
#endif
#ifdef M15TH
main;
#endif
#ifdef M16TH


void main(){*((char*)0)='+'+'+'/'-'-'-';}

#endif


Dan Pop

unread,
Apr 10, 1997, 3:00:00 AM4/10/97
to

In <ptcu3lg...@hammer.thor.cam.ac.uk> ey...@thor.cam.ac.uk (E. Young) writes:

>main(){puts(0);}
>
>Is the lack of a defn for puts() a good or bad thing in this
>context? ;)

The definition of puts is provided by the library. You must be talking
about a declaration for puts. It wouldn't have any effect, because your
call is compatible with the standard prototype for puts.

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

Dan Pop

unread,
Apr 10, 1997, 3:00:00 AM4/10/97
to

In <5ihd57$s...@mtinsc04.worldnet.att.net> Craig Franck <clfr...@worldnet.att.net> writes:

>"Tim Behrendsen" <t...@a-sis.com> wrote:
>>Tim Behrendsen <t...@a-sis.com> wrote in article <01bc44f2$a53639a0$87ee6fce@timpent.a-

>>> Shortest divide by zero fault?
>>>
>>> main(){int a=0;a/a;}
>>

>>Actually, this is shorter..
>>
>> int a;main(){a/a;}
>

>Talk about *bloated* code!
>
>main(){1/0;}

The problem is that, bloated or not, it won't dump core on many platforms,
because the compiler won't generate any code for an expression without
any side effects whose value is discarded. This can be fixed only by
adding some code bloat:

main(){return 1/0;}

but now we don't have a winner any longer :-(

My entry:

int main;

Linkers are dumb things, aren't they :-)

Mark Schnitzius

unread,
Apr 10, 1997, 3:00:00 AM4/10/97
to

Craig Franck <clfr...@worldnet.att.net> writes:

>"Tim Behrendsen" <t...@a-sis.com> wrote:
>
>>> Shortest divide by zero fault?
>>>
>>> main(){int a=0;a/a;}
>>
>>Actually, this is shorter..
>>
>> int a;main(){a/a;}

>Talk about *bloated* code!

>main(){1/0;}


My compiler optimized this out, and it ran fine.
How about:

main(a){a/=0;}


(If we're looking for any core, not just a divide by zero
error, I disagree that "int main=0;" or just "int main;"
work; in either case, main will be given a value of 0,
and isn't it possible for a legal instruction to exist
at location zero? I don't think there's any guarantee
that it will crash.)


--Mark

-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
mark schnitzius schn...@mentos.com
<A HREF="http://east.isx.com/~schnitzi/">me</A>
Practice random kindness and senseless acts of extreme violence.

Jens Schweikhardt

unread,
Apr 10, 1997, 3:00:00 AM4/10/97
to

In article <danpop.8...@news.cern.ch> Dan...@cern.ch (Dan Pop) writes:

[snip]

# My entry:
#
# int main;
#
# Linkers are dumb things, aren't they :-)

But isn't int the default? If the above links on your system, wouldn't just

main;

link as well? There! Another four characters squeezed out...

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

Dik T. Winter

unread,
Apr 10, 1997, 3:00:00 AM4/10/97
to

In article <5ijedd$r6c$1...@news.belwue.de> schw...@rubin.noc.dfn.de (Jens Schweikhardt) writes:
> # int main;

> But isn't int the default? If the above links on your system, wouldn't just
> main;
> link as well? There! Another four characters squeezed out...

Would it compile? Only on compilers that are so old that you can nearly
say that they are BK&R.

Da Borg

unread,
Apr 10, 1997, 3:00:00 AM4/10/97
to

Jens Schweikhardt wrote:
[.......]
> # > void main(){*((char*)0)='+'+'+'/'-'-'-';}
[.......]
> # int main(){int x=*(int *)0;}
[........]
> I'd like to jump in on this one and suggest a new contest:
>
> What's the shortest C program likely to dump core?
> (on systems where core dumps are defined by ISO 0401:42)
>
> My entry, probably with enough room for improvement:
>
> main(){*errno/=0;}

The shortest I could come up with:
main(){brk(2/0);}

It produces:

Floating point exception (core dumped)

I am not sure if it's portable though.

--
When sending private email, please remove underscores in "vladi_mip".
#include <disclaimer.h> | *Good pings come in small packets*
vladimip AT uniserve.com | Ceterum censeo Microsoftam delendam esse
Vancouver, B.C. | SIGSIG -- signature too long (core dumped)

Dann Corbit

unread,
Apr 11, 1997, 3:00:00 AM4/11/97
to

It's certainly not ANSI, but it compiles with MSVC++ v 5 with the following
warning:
C:\tmp>cl /W4 tt.c
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 11.00.7022 for 80x86
Copyright (C) Microsoft Corp 1984-1997. All rights reserved.

tt.c
tt.c(1) : warning C4218: nonstandard extension used : must specify at least
a storage class or a type
Microsoft (R) 32-Bit Incremental Linker Version 5.00.7022
Copyright (C) Microsoft Corp 1992-1997. All rights reserved.

/out:tt.exe
tt.obj


Dik T. Winter <d...@cwi.nl> wrote in article <E8G20...@cwi.nl>...

Mike Rubenstein

unread,
Apr 11, 1997, 3:00:00 AM4/11/97
to

k...@vision.crest.nt.com (Kaz Kylheku) wrote:

I think some addition is needed to this post.

Code that results in undefined behavior is incorrect. What may be
correct is code that results in undefined behavior ACCORDING TO THE C
STANDARD. Implementations are free to define extensions that use code
that is not defined by the standard and these may be useful.

Let's consider three examples of undefined behavior.

The code

int main(int argc, char** argv, char** envp)

results in undefined behavior according to the standard, but many
implementations define a meaning for this. As long as one is using
such an implementation (and documents the requirement), there's
nothing wrong with using this construction if the gain offsets the
loss of portability.

The code

void main(void)

also results in undefined behavior according to the standard, but very
few implementations define it. The only one I know of is Microsoft.
I'd not call it an error if one is using Microsoft's compiler and
documents that fact, but here I'd argue that the gain is much too
small to warrant using this construction and consider it very poor
code.

What is not correct is to try it to see if it works. If the
implementation does not document it, it is undefined and should not be
used.

Finally, we have the ever popular

i = i++;

Here I know of no compiler that documents the behavior. Lacking such
documentation, it is incorrect code.

Kaz is correct that the key is ``as long as the programmer knows what
he or she is doing'', but an important point is that unless the
programmer has documentation that defines the behavior for the
implementation(s) he is using, he doesn't know what he is doing.

Michael M Rubenstein

Mike Rubenstein

unread,
Apr 11, 1997, 3:00:00 AM4/11/97
to

Dan...@cern.ch (Dan Pop) wrote:

> In <ptcu3lg...@hammer.thor.cam.ac.uk> ey...@thor.cam.ac.uk (E. Young) writes:
>
> >main(){puts(0);}
> >
> >Is the lack of a defn for puts() a good or bad thing in this
> >context? ;)
>
> The definition of puts is provided by the library. You must be talking
> about a declaration for puts. It wouldn't have any effect, because your
> call is compatible with the standard prototype for puts.

No it isn't. The argument is not the correct type.

Michael M Rubenstein

Jason M. Daniels

unread,
Apr 11, 1997, 3:00:00 AM4/11/97
to

I find it fasciniating that we still manage to quibble about ANSI
compatibility even when we're trying to get the program to crash. :)
Anyhow, here's my entry:

main(){int*a=0;*a=0;}

It's not the shortest that's been posted here, but it's the only one I've
tried that will not only dump core on Unix and Linux machines, but will
"dump core" under DOS when compiled with DJGPP. (of course, DOS can't
actually dump core, but DJGPP does its best to simulate it)

--
Jason Daniels -- bd...@rgfn.epcc.edu


John Hannon

unread,
Apr 11, 1997, 3:00:00 AM4/11/97
to

Jens Schweikhardt wrote:
>
[snip]
> I can live with that... :-)
> Yo, folks. Isn't that much more interesting than hopeless debate threads?
>
Infinitely!
--
=========
John Hannon | john.p...@cpmx.saic.com
Senior Systems Analyst, SAIC

Alex Greenbank

unread,
Apr 11, 1997, 3:00:00 AM4/11/97
to

Jens Schweikhardt (schw...@rubin.noc.dfn.de) wrote:

: In article <danpop.8...@news.cern.ch> Dan...@cern.ch (Dan Pop) writes:

: [snip]

: # My entry:
: #
: # int main;
: #
: # Linkers are dumb things, aren't they :-)

:
: But isn't int the default? If the above links on your system, wouldn't just

: main;

: link as well? There! Another four characters squeezed out...

Worked on SunOS 4.1.4 sun4c, gcc version 2.7.2.2

You've finally discovered the source code to WinBlows 3. They did try
to improve it by bloating it out (almost doubling the source size) for WB95,

int main;

But to no avail.

-Alex (u4...@dcs.shef.ac.uk)

------------------------------------------------------------------------------
Alex Greenbank - 2nd Year Computer Science - Sheffield University - England
u4...@dcs.shef.ac.uk - a.gre...@shef.ac.uk - al...@jumper.mcc.ac.uk
------------------------------------------------------------------------------
"What do you think will be the biggest problem in computing in the 90's?"

"There are only 17,000 three-letter acronyms." - Paul Boutin 1989
------------------------------------------------------------------------------

Jos A. Horsmeier

unread,
Apr 11, 1997, 3:00:00 AM4/11/97
to

Dik T. Winter <d...@cwi.nl> wrote in article <E8G20...@cwi.nl>...
| In article <5ijedd$r6c$1...@news.belwue.de> schw...@rubin.noc.dfn.de (Jens
Schweikhardt) writes:

| > # int main;


| > But isn't int the default? If the above links on your system, wouldn't
just
| > main;
| > link as well? There! Another four characters squeezed out...

| Would it compile? Only on compilers that are so old that you can nearly
| say that they are BK&R.

What happened to all the fun in the world? ;-)

Jos aka j...@and.nl

Tim Behrendsen

unread,
Apr 11, 1997, 3:00:00 AM4/11/97
to

Dan Pop <Dan...@cern.ch> wrote in article <danpop.8...@news.cern.ch>...
>
> My entry:
>
> int main;

>
> Linkers are dumb things, aren't they :-)

Some are smarter than others...

$ cat junk.c
int main;
$ cc junk.c -o junk
0706-317 ERROR: Unresolved or undefined symbols detected:
Symbols in error (followed by references) are
dumped to the load map.
The -bloadmap:<filename> option will create a load map.
.main

(AIX)

Da Borg

unread,
Apr 11, 1997, 3:00:00 AM4/11/97
to

Howdy,

Please allow me to make a contest entry:

$ cat shortcore.c
main(){brk(2/0);}
$ ./shortcore


Floating point exception (core dumped)

$

Thank you,
Da Borg

Dan Pop

unread,
Apr 11, 1997, 3:00:00 AM4/11/97
to

In <5ilf96$q3d$3...@bignews.shef.ac.uk> u4...@dcs.shef.ac.uk (Alex Greenbank) writes:

>Jens Schweikhardt (schw...@rubin.noc.dfn.de) wrote:
>: In article <danpop.8...@news.cern.ch> Dan...@cern.ch (Dan Pop) writes:
>
>: [snip]
>
>: # My entry:
>: #
>: # int main;
>: #

>: # Linkers are dumb things, aren't they :-)
>:
>: But isn't int the default? If the above links on your system, wouldn't just


>
>: main;
>
>: link as well? There! Another four characters squeezed out...

It would link, but it doesn't compile. This is an illegal declaration in C.

>Worked on SunOS 4.1.4 sun4c, gcc version 2.7.2.2

ONLY if you used gcc as a GNU C compiler (and even then you get a
diagnostic). In C mode it barfs:

ues5:~/tmp 6> gcc -pedantic test.c
test.c:1: ANSI C forbids data definition with no type or storage class

Dan
--
Dan Pop
CERN, IT Division
Email: Dan...@cern.ch

John A Cairns

unread,
Apr 11, 1997, 3:00:00 AM4/11/97
to

> Unbelievable, the number of unstandard, unportable unsolutions to
> this unproblem.

Amazing! If you didn't mention this I was going to.

> On UNIX hosts, abort() sends its process a SIGABRT signal, which
> (assuming it is uncaught, and core dumps are not prohibited) causes
> the program to dump core. On other hosts, abort() does whatever is

Actually the SIGABRT signal from abort() can not be caught or ignored
by the calling program. So abort() will still abort even if your program
does its best effort to prevent it.

John
--
John A Cairns
john (at) killyourself com
3.14159265358979323846264338327950288419716939937510582097494459228...

Christopher Green

unread,
Apr 11, 1997, 3:00:00 AM4/11/97
to

Unbelievable, the number of unstandard, unportable unsolutions to
this unproblem.

There is a library function, abort(), that is defined to dump core
on those hosts where dumping core is sensible (and not prohibited):

#include <stdlib.h>
void abort(void);

the shortest use of which (at least, the shortest that gcc -pedantic
doesn't complain about) is:

main(){abort();}

Actually, this is a useful tool in debugging, because one can use
abort() to force a core dump at an arbitrary point in one's program.


On UNIX hosts, abort() sends its process a SIGABRT signal, which
(assuming it is uncaught, and core dumps are not prohibited) causes
the program to dump core. On other hosts, abort() does whatever is

appropriate for that host.

Chris Green Email cgr...@atc.com
Advanced Technology Center Phone (714) 583-9119
22982 Mill Creek Drive ext. 220
Laguna Hills, CA 92653 Fax (714) 583-9213

Jens Schweikhardt

unread,
Apr 12, 1997, 3:00:00 AM4/12/97
to

In article <5imdrl$q...@newshub.atmnet.net> cgr...@yosemite.atc.com (Christopher Green) writes:
# Unbelievable, the number of unstandard, unportable unsolutions to
# this unproblem.
#
# There is a library function, abort(), that is defined to dump core
# on those hosts where dumping core is sensible (and not prohibited):
#
# #include <stdlib.h>
# void abort(void);
#
# the shortest use of which (at least, the shortest that gcc -pedantic
# doesn't complain about) is:
#
# main(){abort();}

Finally! The standard solution. Your entry receives the

'Most Elegant Standard Conformance and Avoiding Undefined Behaviour Award'

# Actually, this is a useful tool in debugging, because one can use
# abort() to force a core dump at an arbitrary point in one's program.
# On UNIX hosts, abort() sends its process a SIGABRT signal, which
# (assuming it is uncaught, and core dumps are not prohibited) causes
# the program to dump core. On other hosts, abort() does whatever is
# appropriate for that host.
#
# Chris Green Email cgr...@atc.com

Peter Seebach

unread,
Apr 12, 1997, 3:00:00 AM4/12/97
to

In article <m2d8s1h...@kill.killyourself.com>,

John A Cairns <jo...@kill.killyourself.com> wrote:
>Actually the SIGABRT signal from abort() can not be caught or ignored
>by the calling program.

HUH?

What gives you this idea?

The only uncatchable signals are nonstandard extensions like SIGKILL and
SIGSTOP. The text defining abort() even discusses how it is affected if
the signal is caught.

-s
--
Copyright 1997 Peter Seebach - seebs at solon.com - C/Unix Wizard
I am not actually gla...@nancynet.com but junk mail is accepted there.
The *other* C FAQ, the hacker FAQ, et al. http://www.solon.com/~seebs
Unsolicited email (junk mail and ads) is unwelcome, and will be billed for.

Dan Pop

unread,
Apr 13, 1997, 3:00:00 AM4/13/97
to

In <01bc4683$d14d5ea0$87ee...@timpent.a-sis.com> "Tim Behrendsen" <t...@a-sis.com> writes:

>Dan Pop <Dan...@cern.ch> wrote in article <danpop.8...@news.cern.ch>...
>>
>> My entry:
>>
>> int main;
>>

>> Linkers are dumb things, aren't they :-)
>

>Some are smarter than others...
>
>$ cat junk.c
>int main;
>$ cc junk.c -o junk
>0706-317 ERROR: Unresolved or undefined symbols detected:
> Symbols in error (followed by references) are
> dumped to the load map.
> The -bloadmap:<filename> option will create a load map.
>.main

Nope, it's not the linker, it's the AIX compiler which doesn't mangle
the symbol names in a consistent way:

cnwgs1:~/tmp 37> cat test.c
extern blah;
int main(){return blah;}
cnwgs1:~/tmp 38> cc test.c
ld: 0711-317 ERROR: Undefined symbol: blah
ld: 0711-345 Use the -bloadmap or -bnoquiet option to obtain more information.
cnwgs1:~/tmp 39> cat test1.c
int main;
cnwgs1:~/tmp 40> cc test1.c
ld: 0711-317 ERROR: Undefined symbol: .main
ld: 0711-345 Use the -bloadmap or -bnoquiet option to obtain more information.

As these examples show, function names get a dot prepended, while
variable names don't.

Greg Stark

unread,
Apr 13, 1997, 3:00:00 AM4/13/97
to

My entries:

main(){++*"";}
main(){*""=0;}
main(){*""/=0;}

Note that other than the last one they aren't actually guaranteed to fail.
I'm not sure what the semantics of the last one are at all for that matter.

greg

Jonas J. Schlein

unread,
Apr 13, 1997, 3:00:00 AM4/13/97
to

>> a = b++ + b;

> Question:
> What is the purpose of writing this expression??
> What were you trying to accomplish??

Without being able to get into the mind of the programmer maybe he was
shooting for something like:

a = 2*b + 1;
b = b + 1;

all in one line? If so then:

a = 2*(b++) + 1;

should work although I'd comment the heck outta that!
--
"If it wasn't for C, we would be using BASI, PASAL, and OBOL."

Jonas J. Schlein (sch...@gl.umbc.edu)

Steve Summit

unread,
Apr 13, 1997, 3:00:00 AM4/13/97
to

In article <5io8r4$1...@solutions.solon.com>, se...@solon.com writes:
>In article <m2d8s1h...@kill.killyourself.com>,
>John A Cairns <jo...@kill.killyourself.com> wrote:
>> Actually the SIGABRT signal from abort() can not be caught or ignored
>> by the calling program.
>
> The only uncatchable signals are nonstandard extensions like SIGKILL and
> SIGSTOP. The text defining abort() even discusses how it is affected if
> the signal is caught.

Well, yeah, but that text leads to a (to me) interesting little
Standard-puzzle: if SIGABRT is indeed caught, and the signal
handler does return, I wonder how abort() can meet the
stipulation that "The abort function cannot return to its
caller." Is abort supposed to be implemented as

while(1)
raise(SIGABRT);

?

[Crossposted to comp.std.c so that I can be embarrassed when
everyone else points out that the answer is obvious...]

Steve Summit
s...@eskimo.com

Nick Maclaren

unread,
Apr 13, 1997, 3:00:00 AM4/13/97
to

In article <E8L8E...@eskimo.com>, Steve Summit <s...@eskimo.com> wrote:
>
>Well, yeah, but that text leads to a (to me) interesting little
>Standard-puzzle: if SIGABRT is indeed caught, and the signal
>handler does return, I wonder how abort() can meet the
>stipulation that "The abort function cannot return to its
>caller." Is abort supposed to be implemented as
>
> while(1) raise(SIGABRT);

More typically:

raise(SIGABRT);
signal(SIGABRT,SIG_DFL);
raise(SIGABRT);

or even:

raise(SIGABRT);
_COME_DOWN_IN_FLAMES_PRONTO();

But the standard does not specify such behaviour in detail.


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

Tanmoy Bhattacharya

unread,
Apr 13, 1997, 3:00:00 AM4/13/97
to

nm...@cus.cam.ac.uk (Nick Maclaren) writes:
<snip>

> >caller." Is abort supposed to be implemented as
> >
> > while(1) raise(SIGABRT);
>
> More typically:
>
> raise(SIGABRT);
> signal(SIGABRT,SIG_DFL);
> raise(SIGABRT);
>
> or even:
>
> raise(SIGABRT);
> _COME_DOWN_IN_FLAMES_PRONTO();
>
> But the standard does not specify such behaviour in detail.

There seems to be a problem with the wording in the standard:

`The implementation shall behave as if no library function calls the
signal function', so the first of the above solutions seems to be
disallowed.

However, `An implementation-defined form of status unsuccesful
termination is returned to the host environment by means of the
function call raise(SIGABRT)'. As the second solution returns the
status by means of the function call _COME_DOWN_IN_FLAMES_PRONTO(),
which is not raise(SIGABRT); that is not valid either.

On the other hand, `while(1) raise(SIGABRT);' does not qualify either,
because abnormal termination is required if the SIGABRT handler
returns.

However, one possible implementation is allowed which follows all
the dictats of the standard in this regard (I think):

0) The initial SIGABRT handler should be SIG_DFL, not SIG_IGN.

When the SIGABRT handler is not SIG_DFL,
1) On the function call abort(), it must set an internal flag.
2) it should reset the SIGABRT handler to SIG_DFL (instead of the
other allowed possibility: block the appropriate signals).
3) it should call the SIGABRT handler.
4) When the SIGABRT handler performs any action which does not allow
it to return any more (e.g. a suitable longjmp etc.), or if the
implementation otherwise determines that the handler won't
return, it resets the internal flag set in step(1). (This is only
a quality of implementation issue).
5) When a call to signal tries to change the SIGABRT handler, and the
internal flag is set, signal should return SIG_ERR and errno should
get set to a positive value, and the call should otherwise be ignored.
6) raise(SIGABRT) is called again if the first call to raise returned.

and
7) If SIGABRT handler is SIG_DFL, and abort is raised, then the program
should terminate with an implementation defined form of status
`unsuccesful termination'.
8) At any time an attempt to set the SIGABRT handler to SIG_IGN should
return SIG_ERR and set errno to a positive value, and the call to
signal should otherwise be ignored. (If quality of
implementation is not at issue, the entire 1-6 above can be eliminated
if any attempt to set the SIGABRT handler does the same).

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,NM87545 H:#9,3000,Trinity Drive,NM87544
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 ]

Lawrence Kirby

unread,
Apr 13, 1997, 3:00:00 AM4/13/97
to

In article <ycq4tdb...@g62-106.citenet.net>
gss...@mit.edu "Greg Stark" writes:

They are all the same - they result in undefined behaviour (both modifying
a string literal and division by 0 invoke undefined behaviour).

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


Dan Pop

unread,
Apr 13, 1997, 3:00:00 AM4/13/97
to

In <5ijjta$b...@oldwood.cs.ucf.edu> schn...@oldwood.cs.ucf.edu (Mark Schnitzius) writes:

>Craig Franck <clfr...@worldnet.att.net> writes:
>
>>"Tim Behrendsen" <t...@a-sis.com> wrote:
>>
>>>> Shortest divide by zero fault?
>>>>
>>>> main(){int a=0;a/a;}
>>>
>>>Actually, this is shorter..
>>>
>>> int a;main(){a/a;}
>
>>Talk about *bloated* code!
>
>>main(){1/0;}
>
>
>My compiler optimized this out, and it ran fine.
>How about:
>
>main(a){a/=0;}
>
>(If we're looking for any core, not just a divide by zero
>error, I disagree that "int main=0;" or just "int main;"
>work; in either case, main will be given a value of 0,
>and isn't it possible for a legal instruction to exist
>at location zero?

You got it wrong. The value of main is zero, NOT its address. So, the
processor will try to execute the instruction whose code is zero and,
if it survives, whatever garbage follows after the address of main.
If the cpu doesn't get caught in a loop very soon, it will cause some
memory protection violation or find a bit pattern which is not a valid
instruction.

>I don't think there's any guarantee that it will crash.)

To get a crash you have to invoke undefined behaviour, but undefined
behaviour, by definition, doesn't guarantee anything. Therefore, none
of the programs quoted above guarantees a crash.

The best guarantee for a crash is offered by calling abort() or
raise(SIGABRT), but these methods require way too many characters to be
interesting :-)

Dan Pop

unread,
Apr 13, 1997, 3:00:00 AM4/13/97
to

It is, if the prototype is in scope.

Lawrence Kirby

unread,
Apr 13, 1997, 3:00:00 AM4/13/97
to

In article <E8L8E...@eskimo.com> s...@eskimo.com "Steve Summit" writes:

>In article <5io8r4$1...@solutions.solon.com>, se...@solon.com writes:
>>In article <m2d8s1h...@kill.killyourself.com>,
>>John A Cairns <jo...@kill.killyourself.com> wrote:
>>> Actually the SIGABRT signal from abort() can not be caught or ignored
>>> by the calling program.
>>
>> The only uncatchable signals are nonstandard extensions like SIGKILL and
>> SIGSTOP. The text defining abort() even discusses how it is affected if
>> the signal is caught.
>

>Well, yeah, but that text leads to a (to me) interesting little
>Standard-puzzle: if SIGABRT is indeed caught, and the signal
>handler does return, I wonder how abort() can meet the
>stipulation that "The abort function cannot return to its

>caller." Is abort supposed to be implemented as
>
> while(1)
> raise(SIGABRT);

7.10.4.1 says:

"The abort function causes abnormal program termination to occur, unless the
signal is being caught and the signal handler does not return."

Therefore if the signal handler does return abort is required to cause
abnormal program termination.

>[Crossposted to comp.std.c so that I can be embarrassed when
>everyone else points out that the answer is obvious...]

Sorry, I read this in comp.lang.c! :-)

meem

unread,
Apr 13, 1997, 3:00:00 AM4/13/97
to

s...@eskimo.com (Steve Summit) writes:

> In article <5io8r4$1...@solutions.solon.com>, se...@solon.com writes:
> >In article <m2d8s1h...@kill.killyourself.com>,
> >John A Cairns <jo...@kill.killyourself.com> wrote:
> >> Actually the SIGABRT signal from abort() can not be caught or ignored
> >> by the calling program.
> >
> > The only uncatchable signals are nonstandard extensions like SIGKILL and
> > SIGSTOP. The text defining abort() even discusses how it is affected if
> > the signal is caught.
>
> Well, yeah, but that text leads to a (to me) interesting little
> Standard-puzzle: if SIGABRT is indeed caught, and the signal
> handler does return, I wonder how abort() can meet the
> stipulation that "The abort function cannot return to its
> caller." Is abort supposed to be implemented as
>
> while(1)
> raise(SIGABRT);

another related question: what if you just longjmp() out of your
SIGABRT handler? ;-)

meem

--
:: me...@sherilyn.wustl.edu :: voice 314/935-1353 :: pager 800/652-2699 ::
:: pgp fingerprint: E7 E8 1A 95 F2 06 6A D6 6A 11 44 D6 6A 6B 93 9B ::
:: GCS v3.12: a-- C+++ UL++++ US++++ UB+++ P++ L+++>++++++ E+>+++ W+ N++ K+ ::
:: w+ O@ M- V- PS+ Y+ PGP++ t+ 5 X R- tv- b DI++ D+ G h+ r- z- ::

Norman Diamond

unread,
Apr 14, 1997, 3:00:00 AM4/14/97
to

In article <E8L8E...@eskimo.com>, s...@eskimo.com (Steve Summit) writes:
>Well, yeah, but that text leads to a (to me) interesting little
>Standard-puzzle: if SIGABRT is indeed caught, and the signal
>handler does return, I wonder how abort() can meet the
>stipulation that "The abort function cannot return to its caller."

By proceeding to abort the program. The abort function does not return
to its caller.

On the other hand, if the signal handler *doesn't* return, then the program
doesn't abort. In this case, the abort() function still doesn't return to
its caller. The signal hander might call the caller of the abort()
function, but that's different from a hypothetical return from abort().

Incidentally regarding the subject of this thread, a strictly conforming
program cannot dump core. The standard does not force abort() to dump
core, and a strictly conforming program cannot output dumps depending on
implementation extensions.
--
<< If this were the company's opinion, I would not be allowed to post it. >>
"I paid money for this car, I pay taxes for vehicle registration and a driver's
license, so I can drive in any lane I want, and no innocent victim gets to call
the cops just 'cause the lane's not goin' the same direction as me" - J Spammer

Christian Bau

unread,
Apr 14, 1997, 3:00:00 AM4/14/97
to

In article <5igpbc$d...@ratty.wolfe.net>,
Rich Miller <rmi...@WOLFENET.COM> wrote:
>In article <christian.bau-0...@christian-mac.isltd.insignia.com>,
>Christian Bau <christ...@isltd.insignia.comm> wrote:
>
>> ... My own attitude is that code that causes undefined behavior
>> is not bad through that fact alone, as long as the programmer knows what
>> he is doing.
>
>This is an astounding statement! -- or at least it should be. Unfortunately,
>many programmers seem to share a similar attitude, and we as a community
>are most definitely impacted by the buggy code that seems the inevitable
>result of such lack of concern for "doing the right thing".

I am not sure how you read "programmer knows what he/she is doing". You
might argue that a programmer who writes crap and knows that he writes
crap "knows what he is doing", but I didnt think anyone would read it like
this. Quoting me out of context changed the meaning a bit. My post was
like this:

xxx claims: "It works for me and I dont care if it is undefined behavior"
I wrote: "Undefined behavior is ok if you know what you are doing, but
you seem not to know for the following reasons... (followed by a dozen
reason why i++ + ++i would be a bad idea even if it was not undefined
behavior).

Just an example of three lines of code with two cases of undefined behavior:

#ifndef __GESTALT__
#include <Gestalt.h>
#endif

Programmers who dont know what they are doing might prefer the following,
which is only one case of undefined behavior:

#include <Gestalt.h>

If a non-trivial Macintosh program doesnt include any of these lines, I
would suspect that maybe the programmer isnt very competent at all
(typical effect of not including <Gestalt.h> is that the program runs on
the programmers machine, but crashes on any other machine). So you say
that by definition all Macintosh code is buggy. Also by definition all
Windows code is buggy. Also all POSIX code is buggy. By the way, the ANSI
C standard doesnt define the behavior of FORTRAN or ADA programs, so
FORTRAN and ADA programs cause undefined behavior.

You might find the following lines in C programs written by competent
Macintosh programmers:

#ifdef DEVELOPMENT
* (long *) 0 = 0xa9ff5eff
#endif

This is an extreme case of undefined behavior. Extremly unportable and
extremly useful on Macintosh computers, and I wont tell you why.

-- For email responses, please remove the last emm from my address.
-- For spams, please send them to whereever...@but.not.here

Mark Schnitzius

unread,
Apr 14, 1997, 3:00:00 AM4/14/97
to

In article <danpop.8...@news.cern.ch>,

> >>main(){1/0;}
> >
> >
> >My compiler optimized this out, and it ran fine.
> >How about:
> >
> >main(a){a/=0;}
> >
> >(If we're looking for any core, not just a divide by zero
> >error, I disagree that "int main=0;" or just "int main;"
> >work; in either case, main will be given a value of 0,
> >and isn't it possible for a legal instruction to exist
> >at location zero?
>
> You got it wrong. The value of main is zero, NOT its address. So, the
> processor will try to execute the instruction whose code is zero and,
> if it survives, whatever garbage follows after the address of main.


I disagree. I'm fairly certain that the symbol "main" holds an
address into the text area where the program is to begin. This is
why an IOCCC winner from way back works (from
http://reality.sgi.com/csp/ioccc/years.html#1984_mullender):

short main[] = {
277, 04735, -4129, 25, 0, 477, 1019, 0xbef, 0, 12800,
-113, 21119, 0x52d7, -1006, -7151, 0, 0x4bc, 020004,
14880, 10541, 2056, 04010, 4548, 3044, -6716, 0x9,
4407, 6, 5568, 1, -30460, 0, 0x9, 5570, 512, -30419,
0x7e82, 0760, 6, 0, 4, 02400, 15, 0, 4, 1280, 4, 0,
4, 0, 0, 0, 0x8, 0, 4, 0, ',', 0, 12, 0, 4, 0, '#',
0, 020, 0, 4, 0, 30, 0, 026, 0, 0x6176, 120, 25712,
'p', 072163, 'r', 29303, 29801, 'e'
};


Here, "main" holds a pointer to the first instruction. I still
maintain that "int main;" will cause execution to start at location
zero.


--Mark

-------------------==== Posted via Deja News ====-----------------------
http://www.dejanews.com/ Search, Read, Post to Usenet

Billy Chambless

unread,
Apr 14, 1997, 3:00:00 AM4/14/97
to

In article <c44_970...@crystals.aloha.or.us>, Scott....@p653.f40.n105.z1.fidonet.org (Scott Staples) writes:

|> > | a = ++i + ++i;
|> > | a gets assigned 4;

|> > | I see nothing unexpected about this. I don't care whether is
|> > | 'non standard' or whatever, the fact is that it works.

|> h > Picking up my black book and writing down:

|> h > Never hire Brian Ross, ever.
|> h > Never use a program written by Brian Ross.
|> h > Never trust products from the company that hires Brian Ross.

|> Why not? If it works, use it, right?

It depends on how you define "works".

The example above "works" in the sense that it does what one person
thinks it will do on one machine with one compiler.

The whole thing about using code that invokes undefined behavior
needlessly is that you can't predict what it will do on another
platform, or with another compiler, or even (sometimes) the next time
it's run.

I have to agree with Goran -- I would never hire a programmer who
had such a sloppy definition of "works".

Learn from history: way back when, many programmers did a lot of
stuff that "worked" on Vaxes. Their code died horribly a few years later
when it had to be moved to workstations. The same thing will happen to
people who get in the habit of writing code that "works" on a PeeCee
using the Borland compiler, rather than writing portable code.
--
* "We all agree on the necessity of compromise. We just can't agree on
* when it's necessary to compromise."
* --Larry Wall in <1991Nov13.1...@netlabs.com>


Billy Chambless

unread,
Apr 14, 1997, 3:00:00 AM4/14/97
to

In article <ptcvi5p...@hammer.thor.cam.ac.uk>, ey...@thor.cam.ac.uk (E. Young) writes:
|> [atrributions are screwed. as far as I can see... ]


|> > a = ++i + ++i;

|> use it and every reason not to. If I employed a C programmer and they
|> wrote that I'd have them hung, drawn and quartered, then reanimated as
|> a zombie and forced to write COBOL until their fingers fell off.

In Dante's Hell, they would be right next to the slimeballs who don't
check the results of fopen() and malloc().

Scott Staples

unread,
Apr 14, 1997, 3:00:00 AM4/14/97
to

> | i = 0;

> | a = ++i + ++i;
> | a gets assigned 4;
> |
> | I see nothing unexpected about this. I don't care whether is
> | 'non standard' or whatever, the fact is that it works.

h > Picking up my black book and writing down:

h > Never hire Brian Ross, ever.
h > Never use a program written by Brian Ross.
h > Never trust products from the company that hires Brian Ross.

Why not? If it works, use it, right?

h > Goran Larsson mailto:hoh @ approve . se
h > I was an atheist, http://home1.swipnet . se/%7Ew-12153/
h > until I found out I was God. < Then you must not exist.

h > ---
h > * Origin: *The Crystal Ship* PDX Fido<>Usenet Gateway (1:105/306.999)

It is loading more messages.
0 new messages