Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Arg Eval

Reply
Thread Tools

Arg Eval

 
 
Gordon Burditt
Guest
Posts: n/a
 
      10-22-2005
>> > #include <stdio.h>
>> >
>> > int main(void)
>> > {
>> > int n = 1;
>> >
>> > /* They'd like this to result in 1, 10, 100.
>> > */
>> > printf("%d %d %d", n, n *= 10, n *= 10);

>>
>> This invokes undefined behaviour, which means that literally anything
>> can happen.
>> 1) n is modified twice without an intervening sequence point which is
>> undefined behaviour

>
>Isn't the comma operator a sequence point?


There are no comma operators in the above code.

>Moreover, isn't the passing
>each argument a sequence point in of itself?


No.

Gordon L. Burditt
 
Reply With Quote
 
 
 
 
Chris Torek
Guest
Posts: n/a
 
      10-22-2005
In article <djbpg3$jrb$(E-Mail Removed)> rayw <(E-Mail Removed)> wrote:
>Could someone give me the name of a compiler/environment where this code
>[below] evaluates left to right (or, at least not right to left!) ...
>all the gcc implentations I have to hand does this right to left.
>So, I'd like to give a concrete counter example.
>
>#include <stdio.h>
>
>int main(void)
>{
> int n = 1;
>
> /* They'd like this to result in 1, 10, 100.
> */
> printf("%d %d %d", n, n *= 10, n *= 10);
>
> return 0;
>}


Indeed, as everyone else has noted, this results in undefined
behavior. The question, however, is whether someone has an example
system on which (a) output is produced, and (b) the output is
"1 10 100". (It would help to add a newline.)

The old Pyramid C compiler would have done that, as it evaluated
the first 12 arguments left-to-right. Arguments beyond the first
twelve were evaluated right-to-left (and before the first twelve
were handled left-to-right). This was because most parameters are
passed in the Parameter Registers, pr0 through pr11 inclusive,
while those that do not fit are passed on a conventional stack.
(In the callee, the registers are named pr0 through pr11 -- the
caller addresses them as tr0 through tr11, the temporary or transfer
registers. Normally these are available for scratch computations.
Return values go in pr0 so that the caller sees them in tr0.)

It is generally difficult to find compilers that work strictly
L-to-R: good compilers often seem to do the evaluation in "apparently
random order", while poor compilers usually do them in whatever
order is easiest on the target hardware, and common target hardware
happens to cause the latter to be R-to-L.

Presumably the reason for the desire for "1 10 100" output is to
demonstrate that not all compilers produce "100 10 1", in an effort
to convince programmers that they should avoid such code. But
those who will not be convinced by the text of the C Standards
might also not be convinced by counterexamples: "Why, those compilers
are just broken," they might say.

Still, one handy counterexample I have is a Mac G4 (PowerPC) running
OS X 10.2 (one of these days I should upgrade it). After fixing
the code above to include a terminating newline, and compiling with
"cc" (which is Apple GCC version 1175 "based on gcc version 3.1
20020420 (prerelease)"), I get:

% cc -o t t.c
% ./t
100 10 100

The output remains unchanged when optimized (with -O or -O2).

The PowerPC, MIPS, and SPARC are three good architectures to
try, as all three generally use registers for parameter-passing.

Note that calling a function other than printf() might change the
result on some machines, because printf() is a variable-argument
function, and there are good reasons to want to use different
calling conventions for fixed vs variable argument functions.
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (4039.22'N, 11150.29'W) +1 801 277 2603
email: forget about it http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.
 
Reply With Quote
 
 
 
 
Flash Gordon
Guest
Posts: n/a
 
      10-22-2005
Razzer wrote:
> Flash Gordon wrote:
>
>>rayw wrote:
>>
>>>#include <stdio.h>
>>>
>>>int main(void)
>>>{
>>> int n = 1;
>>>
>>> /* They'd like this to result in 1, 10, 100.
>>> */
>>> printf("%d %d %d", n, n *= 10, n *= 10);

>>
>>This invokes undefined behaviour, which means that literally anything
>>can happen.
>>1) n is modified twice without an intervening sequence point which is
>> undefined behaviour

>
> Isn't the comma operator a sequence point? Moreover, isn't the passing
> each argument a sequence point in of itself?


Other have noted there is no comma operator and there no sequence point
between evaluation of parameters.

>>2) n is used for a purpose other than calculating the new value of n
>> which I believe also invokes undefined behaviour.

>
> Only if it is in the same expression.


No, between sequence points. In section 6.5 of N1224 it says
| 2 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 read only to
| determine the value to be stored.71)

No where does it say this only applies to individual expressions. If it
did then it would make this explicit. So
printf("%d %d", n, n *= 10);
would also be undefined behaviour in my opinion since you are reading n
for a purpose other than calculating its new value between sequence points.
--
Flash Gordon
Living in interesting times.
Although my email address says spam, it is real and I read it.
 
Reply With Quote
 
rayw
Guest
Posts: n/a
 
      10-23-2005

"Chris Torek" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
> In article <djbpg3$jrb$(E-Mail Removed)> rayw <(E-Mail Removed)>
> wrote:
>>Could someone give me the name of a compiler/environment where this code
>>[below] evaluates left to right (or, at least not right to left!) ...
>>all the gcc implentations I have to hand does this right to left.
>>So, I'd like to give a concrete counter example.
>>
>>#include <stdio.h>
>>
>>int main(void)
>>{
>> int n = 1;
>>
>> /* They'd like this to result in 1, 10, 100.
>> */
>> printf("%d %d %d", n, n *= 10, n *= 10);
>>
>> return 0;
>>}

>
> Indeed, as everyone else has noted, this results in undefined
> behavior. The question, however, is whether someone has an example
> system on which (a) output is produced, and (b) the output is
> "1 10 100". (It would help to add a newline.)
>
> The old Pyramid C compiler would have done that, as it evaluated
> the first 12 arguments left-to-right. Arguments beyond the first
> twelve were evaluated right-to-left (and before the first twelve
> were handled left-to-right). This was because most parameters are
> passed in the Parameter Registers, pr0 through pr11 inclusive,
> while those that do not fit are passed on a conventional stack.
> (In the callee, the registers are named pr0 through pr11 -- the
> caller addresses them as tr0 through tr11, the temporary or transfer
> registers. Normally these are available for scratch computations.
> Return values go in pr0 so that the caller sees them in tr0.)
>
> It is generally difficult to find compilers that work strictly
> L-to-R: good compilers often seem to do the evaluation in "apparently
> random order", while poor compilers usually do them in whatever
> order is easiest on the target hardware, and common target hardware
> happens to cause the latter to be R-to-L.
>
> Presumably the reason for the desire for "1 10 100" output is to
> demonstrate that not all compilers produce "100 10 1", in an effort
> to convince programmers that they should avoid such code. But
> those who will not be convinced by the text of the C Standards
> might also not be convinced by counterexamples: "Why, those compilers
> are just broken," they might say.
>
> Still, one handy counterexample I have is a Mac G4 (PowerPC) running
> OS X 10.2 (one of these days I should upgrade it). After fixing
> the code above to include a terminating newline, and compiling with
> "cc" (which is Apple GCC version 1175 "based on gcc version 3.1
> 20020420 (prerelease)"), I get:
>
> % cc -o t t.c
> % ./t
> 100 10 100
>
> The output remains unchanged when optimized (with -O or -O2).
>
> The PowerPC, MIPS, and SPARC are three good architectures to
> try, as all three generally use registers for parameter-passing.
>
> Note that calling a function other than printf() might change the
> result on some machines, because printf() is a variable-argument
> function, and there are good reasons to want to use different
> calling conventions for fixed vs variable argument functions.


That's just the job - ta.

I should have made it clear that I'm teaching this course, and that the code
was entered by a student. Obviously, I explained the mistake, and then
actually walked through what was happening here with the class.

All I was after -just for interest'ss sake- was the name of a compiler that
happened to eval left to right.

rayw



 
Reply With Quote
 
Jalapeno
Guest
Posts: n/a
 
      10-24-2005

rayw wrote:
> Could someone give me the name of a compiler/environment where this code
> [below] evaluates left to right (or, at least not right to left!) - as in
> the compiler evaluates the parameter
> list left to right. This is for a c programming class, and all the gcc
> implentations I have to hand does this right to left. So, I'd like to give
> a concrete counter example.
>
> #include <stdio.h>
>
> int main(void)
> {
> int n = 1;
>
> /* They'd like this to result in 1, 10, 100.
> */
> printf("%d %d %d", n, n *= 10, n *= 10);
>
> return 0;
> }


The z/OS C version 1 release 6 compiler from IBM for their Mainframes:
(This was compiled and run in batch under JES2)

5694A01 V1 R6 z/OS C 'SYS05297.T091012.RA000.T9232EHD.SOURCE.H02'


* * * * * S O U R C E * * * * *


LINE STMT


*...+....1....+....2....+....3....+....4....+....5 ....+....6....+.
1 |#include <stdio.h>

2 |

3 |int main(void)

4 |{

5 1 | int n = 1;

6 |

7 | /* They'd like this to result in 1, 10, 100.

8 | */

9 2 | printf("%d %d %d", n, n *= 10, n *= 10);

10 |

11 3 | return 0;

12 |}

* * * * * E N D O F S O U R C E * *


Display Filter View Print Options Help
------------------------------------------------------------------
SDSF OUTPUT DISPLAY T9232EHB JOB17312 DSID 102 LINE 0 COL
COMMAND INPUT ===> SCRO
********************************* TOP OF DATA *********************
1 10 100
******************************** BOTTOM OF DATA *******************

 
Reply With Quote
 
rayw
Guest
Posts: n/a
 
      10-24-2005

"Jalapeno" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed) oups.com...
>
> rayw wrote:
>> Could someone give me the name of a compiler/environment where this code
>> [below] evaluates left to right (or, at least not right to left!) - as in
>> the compiler evaluates the parameter
>> list left to right. This is for a c programming class, and all the gcc
>> implentations I have to hand does this right to left. So, I'd like to
>> give
>> a concrete counter example.
>>
>> #include <stdio.h>
>>
>> int main(void)
>> {
>> int n = 1;
>>
>> /* They'd like this to result in 1, 10, 100.
>> */
>> printf("%d %d %d", n, n *= 10, n *= 10);
>>
>> return 0;
>> }

>
> The z/OS C version 1 release 6 compiler from IBM for their Mainframes:
> (This was compiled and run in batch under JES2)
>
> 5694A01 V1 R6 z/OS C 'SYS05297.T091012.RA000.T9232EHD.SOURCE.H02'
>
>
> * * * * * S O U R C E * * * * *
>
>
> LINE STMT
>
>
> *...+....1....+....2....+....3....+....4....+....5 ....+....6....+.
> 1 |#include <stdio.h>
>
> 2 |
>
> 3 |int main(void)
>
> 4 |{
>
> 5 1 | int n = 1;
>
> 6 |
>
> 7 | /* They'd like this to result in 1, 10, 100.
>
> 8 | */
>
> 9 2 | printf("%d %d %d", n, n *= 10, n *= 10);
>
> 10 |
>
> 11 3 | return 0;
>
> 12 |}
>
> * * * * * E N D O F S O U R C E * *
>
>
> Display Filter View Print Options Help
> ------------------------------------------------------------------
> SDSF OUTPUT DISPLAY T9232EHB JOB17312 DSID 102 LINE 0 COL
> COMMAND INPUT ===> SCRO
> ********************************* TOP OF DATA *********************
> 1 10 100
> ******************************** BOTTOM OF DATA *******************
>


Excellent - thanks!


 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
eval('07') works, eval('08') fails, why? Alex van der Spek Python 6 01-08-2009 08:24 PM
How to pass a multiline arg to exec('some.exe arg')? n00m Python 5 05-05-2008 02:58 PM
DataBinder.Eval and Eval. craigkenisston@hotmail.com ASP .Net 1 06-16-2006 05:33 PM
Trouble with setTimeout(arg, arg) nat.hourt@gmail.com Javascript 7 11-12-2005 05:13 PM
DataBinder.Eval for an object's property property... like Eval(Container.DataItem,"Version.Major") Eric Newton ASP .Net 3 04-04-2005 10:11 PM



Advertisments