Author: Dann Corbit
Date: 21:45:36 12/14/01
Go up one level in this thread
On December 15, 2001 at 00:10:00, Paul Byrne wrote:
>Not sure if it is the compiler that is stupid or the question... :)
>
>When I started using the MS compiler recently I discovered that rand()
>is only 16 bits & just hacked this together to get things running...
>[yes, I know rand() is evil, but ignore that for a moment :)]
>
>unsigned rand32()
>{
> return (unsigned) (rand() ^ (rand()<<7) ^ (rand()>>7) ^
> (rand()<<17) ^ (rand()>>17) ^ (rand()<<23) ^ (rand()>>23));
>}
>
>Problem is, this returns different things in debug and release mode,
>which stops my opening books from functioning in debug mode.
>rand() is returning the same sequence of integers, so I'm assuming
>the optimizer is messing with the order of the calls (I'm just using
>the default maximize speed settings).
>
>Shouldn't the ^ operator always be left to right?
>
>Am I missing something here, or is the compiler breaking the rules? :)
It's a common {wrong} behavior:
Compiling...
foo.c
icl: Command line warning: overriding '-O2' with '-O3'
icl: NOTE: The evaluation period for this product ends on 15-mar-2002 UTC.
C:\\tmp\\foo.c(5): remark #981: operands are evaluated in unspecified order
return (unsigned) (rand() ^ (rand()<<7) ^ (rand()>>7) ^
^
C:\\tmp\\foo.c(5): remark #981: operands are evaluated in unspecified order
return (unsigned) (rand() ^ (rand()<<7) ^ (rand()>>7) ^
^
C:\\tmp\\foo.c(5): remark #981: operands are evaluated in unspecified order
return (unsigned) (rand() ^ (rand()<<7) ^ (rand()>>7) ^
^
C:\\tmp\\foo.c(6): remark #981: operands are evaluated in unspecified order
(rand()<<17) ^ (rand()>>17) ^ (rand()<<23) ^ (rand()>>23));
^
C:\\tmp\\foo.c(6): remark #981: operands are evaluated in unspecified order
(rand()<<17) ^ (rand()>>17) ^ (rand()<<23) ^ (rand()>>23));
^
C:\\tmp\\foo.c(6): remark #981: operands are evaluated in unspecified order
(rand()<<17) ^ (rand()>>17) ^ (rand()<<23) ^ (rand()>>23));
^
From the C FAQ:
3.8: How can I understand these complex expressions? What's a
"sequence point"?
A: A sequence point is a point in time (at the end of the
evaluation of a full expression, or at the ||, &&, ?:, or comma
operators, or just before a function call) at which the dust
has settled and all side effects are guaranteed to be complete.
The ANSI/ISO C Standard states that
Between the previous and next sequence point an
object shall have its stored value modified at
most once by the evaluation of an expression.
Furthermore, the prior value shall be accessed
only to determine the value to be stored.
The second sentence can be difficult to understand. It says
that if an object is written to within a full expression, any
and all accesses to it within the same expression must be for
the purposes of computing the value to be written. This rule
effectively constrains legal expressions to those in which the
accesses demonstrably precede the modification.
See also question 3.9 below.
References: ISO Sec. 5.1.2.3, Sec. 6.3, Sec. 6.6, Annex C;
Rationale Sec. 2.1.2.3; H&S Sec. 7.12.1 pp. 228-9.
From high priority to low priority, here is the operator precedence:
( ) [ ] -> .
! - * & sizeof cast ++ -
(these are right->left)
* / %
+ -
< <= >= >
== !=
&
|
&&
||
?: (right->left)
= += -= (right->left)
, (comma)
Now, for operators of the same precedence we should parse from left to right.
They don't really have to do it like that, but they have to follow the AS-IF
rule (IOW, the results should be the same as if they followed the right order,
if they actually use a different order).
I expect they will tell you to turn the optimizer off. They are breaking the
rules (but so do lots of vendors.)
This page took 0 seconds to execute
Last modified: Thu, 15 Apr 21 08:11:13 -0700
Current Computer Chess Club Forums at Talkchess. This site by Sean Mintz.