csp@gtenmc.UUCP (csp) (09/26/90)
Assuming that the 2's complement system is used to represent the negative
integers. I wrote the following code , and the results I got were absurd.
C code :
main()
{
int a;
printf(" Maxint : %d\na = %d\n", ( int )(( unsigned ) ~0 >> 1 ) ,
a = ( int )(( unsigned ) ( a = ~0 ) >> 1 ));
}
Output :
Maxint : -1
a = 2147483647
Can some complier writer tell me why this is happening ?
csp - csp@gtenmc.UUCP
K&R C > ANSI C
eager@ringworld.Eng.Sun.COM (Michael J. Eager) (09/26/90)
In article <884@gtenmc.UUCP> csp@gtenmc.UUCP (Charudutta S Palkar) writes: > > Assuming that the 2's complement system is used to represent the negative > integers. I wrote the following code , and the results I got were absurd. > >C code : > > main() > { > int a; > printf(" Maxint : %d\na = %d\n", ( int )(( unsigned ) ~0 >> 1 ) , > a = ( int )(( unsigned ) ( a = ~0 ) >> 1 )); > } > > Output : > > Maxint : -1 > a = 2147483647 > >Can some complier writer tell me why this is happening ? > >csp - csp@gtenmc.UUCP > >K&R C > ANSI C The right shift operator is not clearly defined when applied to signed integers. It looks like your compiler does a logical right shift, which inserts a high order zero bit. The assignment of a = ~0 will make a = -1. When this is shifted right by one bit, and the sign bit is set to zero, a becomes MAXINT, which you then converted to unsigned and then int, neither of which change its value. -- Mike Eager
bomgard@iuvax.cs.indiana.edu (Tim Bomgardner) (09/26/90)
In article <884@gtenmc.UUCP> csp@gtenmc.UUCP (Charudutta S Palkar) writes: } } Assuming that the 2's complement system is used to represent the negative } integers. I wrote the following code , and the results I got were absurd. } }C code : } } main() } { } int a; } printf(" Maxint : %d\na = %d\n", ( int )(( unsigned ) ~0 >> 1 ) , } a = ( int )(( unsigned ) ( a = ~0 ) >> 1 )); } } } } Output : } } Maxint : -1 } a = 2147483647 } }Can some complier writer tell me why this is happening ? } }csp - csp@gtenmc.UUCP } }K&R C > ANSI C The value for a is exactly what I would expect: pow(2,31)-1. The question is is ~0 in the expression ((unsigned) ~0 >> 1) signed or unsigned. If it is signed, then the result is implementation-defined and can be either a logical or an arithmetic shift. -1 is the correct result for an arithmetic shift. However, you have a valid cast, so ~0 is unsigned and a logical shift should be performed. I believe your compiler is in error.
henry@zoo.toronto.edu (Henry Spencer) (09/27/90)
In article <884@gtenmc.UUCP> csp@gtenmc.UUCP (Charudutta S Palkar) writes: > ... I wrote the following code , and the results I got were absurd. > > printf(" Maxint : %d\na = %d\n", ( int )(( unsigned ) ~0 >> 1 ) , > a = ( int )(( unsigned ) ( a = ~0 ) >> 1 )); Sure you know what the results should be? The second expression is assigning to `a' twice, which has unpredictable effects. However, this doesn't explain what you're seeing. It does look to me like a compiler bug. -- TCP/IP: handling tomorrow's loads today| Henry Spencer at U of Toronto Zoology OSI: handling yesterday's loads someday| henry@zoo.toronto.edu utzoo!henry
burley@world.std.com (James C Burley) (09/27/90)
In article <1990Sep26.175948.8232@zoo.toronto.edu> henry@zoo.toronto.edu (Henry Spencer) writes: In article <884@gtenmc.UUCP> csp@gtenmc.UUCP (Charudutta S Palkar) writes: > ... I wrote the following code , and the results I got were absurd. > > printf(" Maxint : %d\na = %d\n", ( int )(( unsigned ) ~0 >> 1 ) , > a = ( int )(( unsigned ) ( a = ~0 ) >> 1 )); Sure you know what the results should be? The second expression is assigning to `a' twice, which has unpredictable effects. However, this doesn't explain what you're seeing. It does look to me like a compiler bug. Hmm, I thought it was ok -- doesn't "=" serve as a "sequence point" or some such thing, and since the lhs of the outer = is so simple it can't be "evaluated" before the rhs has been, and the rhs contains the other =, one is guaranteed the latter = is performed before the former, right? On the other hand, "b = a + (int)((unsigned)(a=~0)>>1));" would be undefined as to whether the first mention of "a" identifies the value it holds prior to execution of the statement or the value ~0. James Craig Burley, Software Craftsperson burley@world.std.com
henry@zoo.toronto.edu (Henry Spencer) (09/27/90)
In article <143014@sun.Eng.Sun.COM> eager@ringworld.Eng.Sun.COM (Michael J. Eager) writes: >> printf(" Maxint : %d\na = %d\n", ( int )(( unsigned ) ~0 >> 1 ) , >The assignment of a = ~0 will make a = -1. When this is shifted >right by one bit, and the sign bit is set to zero, a becomes >MAXINT, which you then converted to unsigned and then int... Careful... Casts bind tighter than binary operators; the unsigned conversion is being done *before* the shift. -- TCP/IP: handling tomorrow's loads today| Henry Spencer at U of Toronto Zoology OSI: handling yesterday's loads someday| henry@zoo.toronto.edu utzoo!henry
benyukhi@motcid.UUCP (Ed Benyukhis) (09/28/90)
In article <143014@sun.Eng.Sun.COM>, eager@ringworld.Eng.Sun.COM (Michael J. Eager) writes: > In article <884@gtenmc.UUCP> csp@gtenmc.UUCP (Charudutta S Palkar) writes: > > int a; > > printf(" Maxint : %d\na = %d\n", ( int )(( unsigned ) ~0 >> 1 ) , > > a = ( int )(( unsigned ) ( a = ~0 ) >> 1 )); > > Output : > > Maxint : -1 > > a = 2147483647 > >Can some complier writer tell me why this is happening ? > > The right shift operator is not clearly defined when applied to > signed integers. It looks like your compiler does a logical > right shift, which inserts a high order zero bit. On the contrary, it looks like his compiler does an arithmetic shifts which sign extends i.e. fills vacated bits with the original sign bit. This problem really concerns the "right shifts on signed operands". The language permits the shift to be implemented as an arithmetic shift operation or a logical shift (fill vacated bits with 0's). The choice is left to the compiler writer. "When the left operand of >> is an unsigned type, C mandates a logical shift". Thus declaring a variable to be an unsigned type yields uniform behavior. Ed Benyukhis
henry@zoo.toronto.edu (Henry Spencer) (09/28/90)
In article <BURLEY.90Sep27013312@world.std.com> burley@world.std.com (James C Burley) writes: > Sure you know what the results should be? The second expression is > assigning to `a' twice, which has unpredictable effects... > >Hmm, I thought it was ok -- doesn't "=" serve as a "sequence point" or >some such thing, and since the lhs of the outer = is so simple it can't >be "evaluated" before the rhs has been, and the rhs contains the other >=, one is guaranteed the latter = is performed before the former, right? Wrong. Assignment is not a sequence point. Furthermore, taking the value of an assignment is no guarantee that the assignment has been performed. It's quite legal for the compiler to save up all the assignments and do them at the end of the expression, if that happens to be more convenient. The only constraint is that the update to the lhs must occur somewhere between the previous and the next sequence point. In the absence of intervening sequence points (*some* operators do cause them), the result of modifying an object's value more than once in the same expression is specifically undefined. It might work. It might fail. It might work only when the Moon is full. It might use your modem to place a call to the Pentagon and request an airstrike on your house. :-) -- Imagine life with OS/360 the standard | Henry Spencer at U of Toronto Zoology operating system. Now think about X. | henry@zoo.toronto.edu utzoo!henry
kelley@molecules.ecn.purdue.edu (Stephen Kelley) (09/29/90)
In article <1990Sep28.151723.24287@zoo.toronto.edu> henry@zoo.toronto.edu (Henry Spencer) writes:
[about the definition of 'undefined']
-
- It might use your modem to place
- a call to the Pentagon and request an airstrike on your house. :-)
- --
No doubt this is the ANSI version of Chris Torek's "...make your
monitor explode."
Steve Kelley kelley@flowcyt.ecn.purdue.edu
scjones@thor.UUCP (Larry Jones) (09/29/90)
In article <BURLEY.90Sep27013312@world.std.com>, burley@world.std.com (James C Burley) writes: > > a = ( int )(( unsigned ) ( a = ~0 ) >> 1 )); > > Hmm, I thought it was ok -- doesn't "=" serve as a "sequence point" or > some such thing, and since the lhs of the outer = is so simple it can't > be "evaluated" before the rhs has been, and the rhs contains the other > =, one is guaranteed the latter = is performed before the former, right? No, '=' is not a sequence point. The question in this case is not when the lhs gets evaluated, but when the actual storage of the rhs into the lhs is done. A compiler would be completely within its rights to store the final result into a and then overwrite it with ~0. ---- Larry Jones UUCP: uunet!sdrc!thor!scjones SDRC scjones@thor.UUCP 2000 Eastman Dr. BIX: ltl Milford, OH 45150-2789 AT&T: (513) 576-2070 Yep, we'd probably be dead by now if it wasn't for Twinkies. -- Calvin
hp@vmars.tuwien.ac.at (Peter Holzer) (10/02/90)
scjones@thor.UUCP (Larry Jones) writes: >In article <BURLEY.90Sep27013312@world.std.com>, burley@world.std.com (James C Burley) writes: >> > a = ( int )(( unsigned ) ( a = ~0 ) >> 1 )); >> >No, '=' is not a sequence point. The question in this case is not when >the lhs gets evaluated, but when the actual storage of the rhs into the >lhs is done. A compiler would be completely within its rights to store >the final result into a and then overwrite it with ~0. Yes, but the variable 'a' was not used afterwards, so we are not interested in the value of a, but in the value of the complete expression, which is IMHO well defined (The standard says in 3.3.16: An assignment expression has the value of the left operand after the assignment). Expression: Value: (a = ~0) (int) ~0 (unsigned)(a = ~0) (unsigned) ~0 ((unsigned)(a = ~0) >> 1) (unsigned) MAXINT (int)((unsigned)(a = ~0) >> 1) (int) MAXINT a = (int)((unsigned)(a = ~0) >> 1) (int) MAXINT Anything wrong with my reasoning? -- | _ | Peter J. Holzer | Think of it | | |_|_) | Technische Universitaet Wien | as evolution | | | | | hp@vmars.tuwien.ac.at | in action! | | __/ | ...!uunet!mcsun!tuvie!vmars!hp | Tony Rand |
msb@sq.sq.com (Mark Brader) (10/03/90)
> > > a = ( int )(( unsigned ) ( a = ~0 ) >> 1 )); > > Sure you know what the results should be? The ... expression is > > assigning to `a' twice, which has unpredictable effects. > Hmm, I thought it was ok -- doesn't "=" serve as a "sequence point" or > some such thing, and since the lhs of the outer = is so simple it can't > be "evaluated" before the rhs has been, and the rhs contains the other > =, one is guaranteed the latter = is performed before the former, right? Wrong. First, assignment does not cause a sequence point. The only sequence points are: [1] After evaluating an expression that is not part of another expression; for instance, after an expression statement or after any one of the expressions in a for-header. [2] After evaluating the first operand of one of the operators "?"/":", "&&", "||", "," (conditional expression, logical and/or, or comma). [3] After evaluating the arguments of a function and before calling the function. (Note that the comma between the arguments is not a comma operator, so the arguments may be evaluated in any order, and had better not alter the same variable more than once. Second, even if the rhs did have to be evaluated first, this would not imply that *side-effects* of its evaluation would be executed before the next sequence point. The compiler is free to interpret a = ( int )(( unsigned ) ( a = ~0 ) >> 1 )); as if it was written a = ( int )(( unsigned ) ( tmpa = ~0 ) >> 1 )); a = tmpa; (where tmpa is an otherwise unused variable of the same type as a). Note incidentally that statements like p = p->f = newp; and p->f = p = newp; have undefined effect for the same reason. If you find yourself writing something like this, you should break it up into two statements. -- Mark Brader "It is impractical for the standard to attempt to SoftQuad Inc., Toronto constrain the behavior of code that does not obey utzoo!sq!msb, msb@sq.com the constraints of the standard." -- Doug Gwyn This article is in the public domain.
kdq@demott.COM (Kevin D. Quitt) (10/03/90)
In article <1895@tuvie> hp@vmars.tuwien.ac.at (Peter Holzer) writes: > >Expression: Value: >(a = ~0) (int) ~0 >(unsigned)(a = ~0) (unsigned) ~0 >((unsigned)(a = ~0) >> 1) (unsigned) MAXINT >(int)((unsigned)(a = ~0) >> 1) (int) MAXINT >a = (int)((unsigned)(a = ~0) >> 1) (int) MAXINT > >Anything wrong with my reasoning? Yes. Undefined order or assignment means undefined. It is perfectly legitimate for the (a = ~0) assignment to actually take place after the a = (int)((unsigned)(a = ~0) >> 1) assignment. That's what undefined order means. I agree that a proper compiler "knows" that the former is unnecessary, and can/will be optimized away, but a compiler that isn't that smart *isn't* broken (according to the spec). -- _ Kevin D. Quitt demott!kdq kdq@demott.com DeMott Electronics Co. 14707 Keswick St. Van Nuys, CA 91405-1266 VOICE (818) 988-4975 FAX (818) 997-1190 MODEM (818) 997-4496 PEP last 96.37% of all statistics are made up.
rmj@tcom.stc.co.uk (The Beardless Wonder) (10/03/90)
In article <1895@tuvie> hp@vmars.tuwien.ac.at (Peter Holzer) writes: }scjones@thor.UUCP (Larry Jones) writes: } }>In article <BURLEY.90Sep27013312@world.std.com>, burley@world.std.com (James C Burley) writes: }>> > a = ( int )(( unsigned ) ( a = ~0 ) >> 1 )); }>> } }>No, '=' is not a sequence point. The question in this case is not when }>the lhs gets evaluated, but when the actual storage of the rhs into the }>lhs is done. A compiler would be completely within its rights to store }>the final result into a and then overwrite it with ~0. } }Yes, but the variable 'a' was not used afterwards, so we are not }interested in the value of a, but in the value of the complete }expression, which is IMHO well defined (The standard says in 3.3.16: }An assignment expression has the value of the left operand after the }assignment). The whole point is that "Afterwards" is not a well-defined concept here. The value of the assignment expression is as you say, but as Larry says the value that 'a' has on the far side of the semicolon could be ~0 without contravening the standard. -- * Windsinger * "But soft, what light through yonder * rmj@islay.tcom.stc.co.uk * airlock breaks?" * rmj@tcom.stc.co.uk * --RETURN TO THE FORBIDDEN PLANET * rmj10@phx.cam.ac.uk * You've gotta be cruel to be Khund!
henry@zoo.toronto.edu (Henry Spencer) (10/04/90)
In article <1895@tuvie> hp@vmars.tuwien.ac.at (Peter Holzer) writes: >... the variable 'a' was not used afterwards, so we are not >interested in the value of a, but in the value of the complete >expression, which is IMHO well defined ... By the 3.3 introduction, and the definition of the meaning of "shall" outside constraints, it's not just the value of `a' that is undefined, but the behavior of the entire expression. -- Imagine life with OS/360 the standard | Henry Spencer at U of Toronto Zoology operating system. Now think about X. | henry@zoo.toronto.edu utzoo!henry
hp@vmars.tuwien.ac.at (Peter Holzer) (10/05/90)
kdq@demott.COM (Kevin D. Quitt) writes: >In article <1895@tuvie> hp@vmars.tuwien.ac.at (Peter Holzer) writes: >> >>Expression: Value: >>(a = ~0) (int) ~0 >>(unsigned)(a = ~0) (unsigned) ~0 >>((unsigned)(a = ~0) >> 1) (unsigned) MAXINT >>(int)((unsigned)(a = ~0) >> 1) (int) MAXINT >>a = (int)((unsigned)(a = ~0) >> 1) (int) MAXINT >> >>Anything wrong with my reasoning? > Yes. Undefined order or assignment means undefined. It is >perfectly legitimate for the (a = ~0) assignment to actually take place >after the a = (int)((unsigned)(a = ~0) >> 1) assignment. That's what >undefined order means. I got several replies saying about the same by email, and I think none really covered the point I was making so I will give it a second try with a simpler example: Consider the following expression (initial value of a is 0): a = (a = a + 1) + 1 This will compile (unoptimized) into: tmp1 = a + 1 a = tmp1 * tmp2 = tmp1 + 1 a = tmp2 * where the lines marked with * may or may not be deferred until the next sequence point, making the final value of a undefined, but the value of the whole expression is the value of tmp2, which is not changed by moving the * lines around. The value of (a = a + 1) is 1, the actual assignment takes place sometime before the next sequence point (But we do not know when). So the whole expression (a = (a = a + 1) + 1) becomes (a = (1) + 1) and the value is 2. Again, the assignment a = 2 takes place at some time before the next sequence point. So what we have is that the expression has the value 2, but a may have the value 1 or 2, depending on which assignment takes place first. On the other hand, if we have an expression like (a = a + 1) + (a = a + 1) it will become: tmp1 = a + 1 a = tmp1 * tmp2 = a + 1 a = tmp2 * tmp3 = tmp1 + tmp2 If in this case the compiler decides tho move the line `a = tmp1' the value of tmp2 and thus also the value of tmp3 (which is the value of the whole expression) will change. The compiler might use the initial value for a in both assignments so that the result would be (1) + (1) == 2, or it might evaluate the left subexpression (or the right, doesn't matter in this case), then assign the new value to a, then evaluate the other subexpression with the new value of a, yielding (1) + (2) == 3. Any further comments? -- | _ | Peter J. Holzer | Think of it | | |_|_) | Technical University Vienna | as evolution | | | | | Dept. for Real-Time Systems | in action! | | __/ | hp@vmars.tuwien.ac.at | Tony Rand |
chris@mimsy.umd.edu (Chris Torek) (10/06/90)
In article <1903@tuvie> hp@vmars.tuwien.ac.at (Peter Holzer) writes: >Consider ... a = (a = a + 1) + 1 >This will compile (unoptimized) into: > >tmp1 = a + 1 >a = tmp1 * >tmp2 = tmp1 + 1 >a = tmp2 * > >where the lines marked with * may or may not be deferred until the next >sequence point.... [Second example deleted.] ... Any further comments? Yes. The ANSI standard appears% to allow the compiler to compile it as tmp0 = a tmp1 = tmp0 + 1 a = rand() * tmp2 = tmp0 + 2 a = tmp2 * (using the same notation as above). If the store of tmp2 happens before the store of tmp1, a could wind up with a random value. For a more realistic example, consider a machine that can do several operations at once. This machine might issue two separate `simultaneous' operations, those being `increment a' and `set a=a+2'. This could fetch the value of `a' after the increment has changed only part of the ultimate value (assume it is a parallel machine with lots of one-bit CPUs). The end result is that dreaded word, `undefined'. In short, when the ANSI standard says that the result of an operation is undefined, it means UNDEFINED. The computer can do anything (like turn into a flower)---the system does not have to do anything remotely reasonable. When it says a result is implementation-defined, the system can still do anything, but the product description has to tell you what it does. ----- % Note weasel word. :-) -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 405 2750) Domain: chris@cs.umd.edu Path: uunet!mimsy!chris
wald@theory.lcs.mit.edu (David Wald) (10/07/90)
In article <26875@mimsy.umd.edu> chris@mimsy.umd.edu (Chris Torek) writes: >In short, when the ANSI standard says that the result of an operation >is undefined, it means UNDEFINED. The computer can do anything (like >turn into a flower)---the system does not have to do anything remotely >reasonable. I'm continually amused by the examples people give for undefined and implementation-defined behavior. Can we get a list together, possibly to be incorporated into an Emacs macro? Examples: Melt your screen; Call your mother; Send nasty notes to your boss; ...? -David ``The `#pragma' command is specified in the ANSI standard to have an arbitrary implementation-defined effect. In the GNU C preprocessor, `#pragma' first attempts to run the game `rogue'; if that fails, it tries to run the game `hack'; if that fails, it tries to run GNU Emacs displaying the Tower of Hanoi; if that fails, it reports a fatal error. In any case, preprocessing does not continue.'' -- from the manual for the GCC preprocessor (GCC version 1.34) -- ============================================================================ David Wald wald@theory.lcs.mit.edu ============================================================================
meissner@osf.org (Michael Meissner) (10/07/90)
In article <1990Oct6.194120.27656@mintaka.lcs.mit.edu> wald@theory.lcs.mit.edu (David Wald) writes: | In article <26875@mimsy.umd.edu> chris@mimsy.umd.edu (Chris Torek) writes: | >In short, when the ANSI standard says that the result of an operation | >is undefined, it means UNDEFINED. The computer can do anything (like | >turn into a flower)---the system does not have to do anything remotely | >reasonable. | | I'm continually amused by the examples people give for undefined and | implementation-defined behavior. Can we get a list together, possibly | to be incorporated into an Emacs macro? | | Examples: | | Melt your screen; | Call your mother; | Send nasty notes to your boss; | ...? I tend to use delete the offending source file, after running into an alpha version of a compiler that did that when given a certain invalid switch. | ``The `#pragma' command is specified in the ANSI standard to have an | arbitrary implementation-defined effect. In the GNU C preprocessor, | `#pragma' first attempts to run the game `rogue'; if that fails, it | tries to run the game `hack'; if that fails, it tries to run GNU Emacs | displaying the Tower of Hanoi; if that fails, it reports a fatal | error. In any case, preprocessing does not continue.'' | -- from the manual for the GCC preprocessor (GCC version 1.34) Gcc now does recognize at least one pragma (#pragma once). Here's what's in the source, where it keeps the code around, but #if'ed out: #if 0 /* This was a fun hack, but #pragma seems to start to be useful. By failing to recognize it, we pass it through unchanged to cc1. */ /* * the behavior of the #pragma directive is implementation defined. * this implementation defines it as follows. */ do_pragma () { close (0); if (open ("/dev/tty", O_RDONLY, 0666) != 0) goto nope; close (1); if (open ("/dev/tty", O_WRONLY, 0666) != 1) goto nope; execl ("/usr/games/hack", "#pragma", 0); execl ("/usr/games/rogue", "#pragma", 0); execl ("/usr/new/emacs", "-f", "hanoi", "9", "-kill", 0); execl ("/usr/local/emacs", "-f", "hanoi", "9", "-kill", 0); nope: fatal ("You are in a maze of twisty compiler features, all different"); } #endif -- Michael Meissner email: meissner@osf.org phone: 617-621-8861 Open Software Foundation, 11 Cambridge Center, Cambridge, MA, 02142 Do apple growers tell their kids money doesn't grow on bushes?
friedl@mtndew.Tustin.CA.US (Steve Friedl) (10/09/90)
> /* > * the behavior of the #pragma directive is implementation defined. > * this implementation defines it as follows. > */ > > execl ("/usr/games/hack", "#pragma", 0); ^^^ Can somebody please tell GNU about uncasted NULL pointers? Steve -- Stephen J. Friedl, KA8CMY / I speak for me only / Tustin, CA / 3B2-kind-of-guy +1 714 544 6561 / friedl@mtndew.Tustin.CA.US / {uunet,attmail}!mtndew!friedl "No job is too big, no fee is too big" - Gary W. Keefe's company motto
hp@vmars.tuwien.ac.at (Peter Holzer) (10/09/90)
chris@mimsy.umd.edu (Chris Torek) writes: >In article <1903@tuvie> hp@vmars.tuwien.ac.at (Peter Holzer) writes: >>Consider ... a = (a = a + 1) + 1 >>This will compile (unoptimized) into: >> >>tmp1 = a + 1 >>a = tmp1 * >>tmp2 = tmp1 + 1 >>a = tmp2 * >> >>where the lines marked with * may or may not be deferred until the next >>sequence point.... [Second example deleted.] ... Any further comments? >Yes. The ANSI standard appears% to allow the compiler to compile it >as > tmp0 = a > tmp1 = tmp0 + 1 > a = rand() * > tmp2 = tmp0 + 2 > a = tmp2 * Even in this case the the value of the expression (= tmp2) has the expected value (original value of a) + 2. But in the meantime I have found the following sentence in the introduction to chapter 3.3 (Thanks to Henry Spencer who told me to look there): Between the previous and next sequence point an object shall have its stored value modified at most once by the evaluation of an expression. Together with the sentence in 1.6 Permissible undefined behaviour ranges from ignoring the situation completely with undefined results [...] to terminating a translation or execution [...]. this means that the program might not even compile, or do one or more of the exciting things proposed for undefined behaviour by various people in this group. If however, the compiler decides to be nice to the programmer, and compiles the program to something that has anything to do with the source code, I think that after executing the statements: int a = 0, b; b = (a = (a = a + 1) + 1); b will have the value 2, and a will have a random value (but any other value than 1 or 2 is not very propable). Thanks to all who answered me, I learned something about C again. Regards, Peter. -- | _ | Peter J. Holzer | Think of it | | |_|_) | Technical University Vienna | as evolution | | | | | Dept. for Real-Time Systems | in action! | | __/ | hp@vmars.tuwien.ac.at | Tony Rand |
brnstnd@kramden.acf.nyu.edu (Dan Bernstein) (10/10/90)
In article <542@mtndew.Tustin.CA.US> friedl@mtndew.Tustin.CA.US (Steve Friedl) writes: > > /* > > * the behavior of the #pragma directive is implementation defined. > > * this implementation defines it as follows. > > */ > > execl ("/usr/games/hack", "#pragma", 0); > Can somebody please tell GNU about uncasted NULL pointers? In case you didn't notice, this behavior is *supposed* to be implementation-defined. The code looks right to me... :-) ---Dan