strange behaviour / evaluation order

V

vex

#include <stdio.h>

int main()
{
int a = 1;
int b;
b = a++;
printf( "%d\n", b );
}

gives 1, as you might expect. However;

#include <stdio.h>

int main()
{
int a = 1;
a = a++;
printf( "%d\n", a );
}

gives 2 in the Microsoft compiler, and 1 in the Digital Mars compiler.
I would argue that it should give 1, because "a++" should return 1,
and the postincrement should occur before the assignment, so the value
1 should be assigned to a. Therefore the answer should be 1.

This is some sort of strange evaluation order question, isn't it?
Where the answer is undefined and the standard doesn't say what should
happen? Or did Microsoft mess up :) ? I like Digital Mars's
behaviour better than the Microsoft compiler in this case.

(celci)
 
M

Mudit Khetan

Lets assume that it is a Macro Instruction, one comprising of many
smaller simple instructions. As per ANSI C std. this will be evaluated
in the folloing seq:
1. a = a; --> 1 will be assigned /* post incr. is executed AFTER
the expr has been evaluated completly */
2. a++;
Hence the o/p as per standard will be 2
finally the compiler's manual is the ultimate guide of such
instructions execution plan.
 
K

Keith Thompson

Mudit Khetan said:
Lets assume that it is a Macro Instruction, one comprising of many
smaller simple instructions. As per ANSI C std. this will be evaluated
in the folloing seq:
1. a = a; --> 1 will be assigned /* post incr. is executed AFTER
the expr has been evaluated completly */
2. a++;
Hence the o/p as per standard will be 2
finally the compiler's manual is the ultimate guide of such
instructions execution plan.

That's wrong.

The behavior is undefined.
 
C

Chris Dollin

Mudit said:
Lets assume that it is a Macro Instruction, one comprising of many
smaller simple instructions. As per ANSI C std. this will be evaluated
in the folloing seq:
1. a = a; --> 1 will be assigned /* post incr. is executed AFTER
the expr has been evaluated completly */
2. a++;
Hence the o/p as per standard will be 2

No. The /Standard/ says that this is /undefined/ (because there's
multiple writes to the same place between sequence points).

The compiler can generate whatever code it likes. In practice
this means "whatever my code generator finds convenient". That
might be

mov Rtemp, Ra
add Ra, Ra, #1
mov Ra, Ttemp

This code is no stupider than the source it derives from.
finally the compiler's manual is the ultimate guide of such
instructions execution plan.

The /ultimate/ guide to the compiler's code generation is the
compiler's source code. The ultimate guide to the meaning of
the source code is the Standard plus relevant implementation-
defined bits.
 
P

pete

Mudit said:
Lets assume that it is a Macro Instruction, one comprising of many
smaller simple instructions. As per ANSI C std.
this will be evaluated in the folloing seq:
1. a = a; --> 1 will be assigned /* post incr. is executed AFTER
the expr has been evaluated completly */
2. a++;
Hence the o/p as per standard will be 2

Not "as per standard" at all.
You don't know what you're talking about.
There's two assignment operations in (a = a++)
and the standard doesn't order them.
 
K

Kenneth Brody

pete said:
Not "as per standard" at all.
You don't know what you're talking about.
There's two assignment operations in (a = a++)
and the standard doesn't order them.

And here's a good example of how the claim that "it has to be either
1 or 2" (that is, if "a" has an initial value of 1, as in the OP) is
just not true. (Based on the false assumption that the increment
must take place at some fixed point, either just before or after the
assignment does.)

Consider a CPU with some sort of pipelining, or the ability to
execute more than one instruction at a time.

The first machine-level instruction could be:

Load the value of memory location "a" into register 1.

It could then run the following two instructions in parallel:

Store register 1 into memory location "a".
and
Increment memory location "a".

(This is perfectly fine in the case of "b = a++;", where you would
have "store register 1 into memory location 'b'" instead.)

If the wardware and O/S are built correctly, this should generate
some sort of hardware fault trap, and the O/S will abort the program.

If the hardware is not built correctly (or, perhaps, the O/S doesn't
properly handle the trap), you may lock up the computer, requiring
a power cycle to resolve.

--
+-------------------------+--------------------+-----------------------+
| Kenneth J. Brody | www.hvcomputer.com | #include |
| kenbrody/at\spamcop.net | www.fptech.com | <std_disclaimer.h> |
+-------------------------+--------------------+-----------------------+
Don't e-mail me at: <mailto:[email protected]>
 
F

Flash Gordon

Kenneth said:
And here's a good example of how the claim that "it has to be either
1 or 2" (that is, if "a" has an initial value of 1, as in the OP) is
just not true. (Based on the false assumption that the increment
must take place at some fixed point, either just before or after the
assignment does.)

If the hardware is not built correctly (or, perhaps, the O/S doesn't
properly handle the trap), you may lock up the computer, requiring
a power cycle to resolve.

Or it could damage the processor/memory controller/memory by causeing a
bus clash.
 
V

vex

Or it could damage the processor/memory controller/memory by causeing a
bus clash.

It could electrocute the user. Thus Microsoft Windows Genuine
Advantage could ensure you weren't pirating XP.

On the Sinclair ZX81 there was a memory location where if you poked a
value, after five minutes a counter would decrement to zero and the
machine would crash. On the Commodore PET you could poke a video
controller register so as to cause actual hardware damage to the
screen (I seem to remember). They don't make computers like they used
to.
 
F

Flash Gordon

It could electrocute the user. Thus Microsoft Windows Genuine
Advantage could ensure you weren't pirating XP.

On the Sinclair ZX81 there was a memory location where if you poked a
value, after five minutes a counter would decrement to zero and the
machine would crash. On the Commodore PET you could poke a video
controller register so as to cause actual hardware damage to the
screen (I seem to remember).

On the Camputers Lynx there was a location where if you wrote the wrong
value you could cause a bus clash and damage the computer. This was
documented since there were also potentially valid reasons for writing
to the location (it controlled bank switching).
> They don't make computers like they used
to.

Indeed not. They also don't make monitors like they used to so you can't
blow up a monitor by setting sync rates too high.
 
J

jmcgill

Flash said:
Indeed not. They also don't make monitors like they used to so you can't
blow up a monitor by setting sync rates too high.

Back in the day I searched for any evidence of this actually happening
to anyone. I expect that the failures, where you can find them, were
due not only to setting the sync rate too high, but leaving it there
despite the whiny noise and the fact that all you could see on the
screen was a bright point, or something like this.
 
G

Gordon Burditt

Indeed not. They also don't make monitors like they used to so you can't
Back in the day I searched for any evidence of this actually happening
to anyone. I expect that the failures, where you can find them, were
due not only to setting the sync rate too high, but leaving it there
despite the whiny noise and the fact that all you could see on the
screen was a bright point, or something like this.

I personally witnessed several incidents (and accidentally caused
a couple) with a Tandy Model II/16/6000 in the early '80s. The
monitor wasn't destroyed, but the burnt smell was unmistakable.

The system powered up with the video chip uninitialized (and the
likely problem was that the sync was too high). If you were using
an in-circuit emulator, it would power up with the CPU reset and
paused. If you did not permit the ROM to run the initialization
code fairly quickly (like 15 seconds), it would start frying the
monitor. I think it took something like 4 minutes to actually
permanently ruin the monitor, although nobody timed it to make sure.
If you were near it the smell was unmistakable. The noise was hard
to miss also.

This isn't quite as bad as the usual consequences of fflush(stdin)
on a DS9K, though.
 
K

Kenneth Brody

Just because the failure isn't immediate doesn't mean it's not a
failure.
I personally witnessed several incidents (and accidentally caused
a couple) with a Tandy Model II/16/6000 in the early '80s. The
monitor wasn't destroyed, but the burnt smell was unmistakable.

The system powered up with the video chip uninitialized (and the
likely problem was that the sync was too high). If you were using
an in-circuit emulator, it would power up with the CPU reset and
paused. If you did not permit the ROM to run the initialization
code fairly quickly (like 15 seconds), it would start frying the
monitor. I think it took something like 4 minutes to actually
permanently ruin the monitor, although nobody timed it to make sure.
If you were near it the smell was unmistakable. The noise was hard
to miss also.

Ditto for bank-switching the video memory into the main memory bus,
which would disable something in the video circuitry, and forgetting
to switch it back out. (TRS-DOS II added a print spooler, which was
stored in the bank shared by video memory, and was executed on the
clock interrupt. Forget to disable the interrupt before you switch
the video bank in, and *boom*.) However, in this case, I understood
the problem to be (IIRC) the flyback transformer, and not the display
itself.
This isn't quite as bad as the usual consequences of fflush(stdin)
on a DS9K, though.

I've never actually tried that one, as I've heard rumors that the
consequences were just too horrible to tempt fate. (Of course, I'm
still on the DS6K, so it may not be as bad.)

--
+-------------------------+--------------------+-----------------------+
| Kenneth J. Brody | www.hvcomputer.com | #include |
| kenbrody/at\spamcop.net | www.fptech.com | <std_disclaimer.h> |
+-------------------------+--------------------+-----------------------+
Don't e-mail me at: <mailto:[email protected]>
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,172
Messages
2,570,934
Members
47,474
Latest member
AntoniaDea

Latest Threads

Top