[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.c

Unexpected output

Mazen

9/10/2011 7:36:00 PM

Hello,

Following is a simple program:

#include <stdio.h>

int main(void) {
int i = 0, j, k;
j = k = 2;

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

return 0;
}

The output is
2 2

Shouldn't the second expression be -2 rather than 2? I'm confused.
Your insights pls. Thanks!
29 Answers

arni

9/10/2011 8:32:00 PM

0

On Sep 10, 10:36 pm, Mazen <neuroha...@gmail.com> wrote:
> Hello,
>
> Following is a simple program:
>
> #include <stdio.h>
>
> int main(void) {
>   int i = 0, j, k;
>   j = k = 2;
>
>   printf("%d %d\n", i=+j, i=-j);
>
>   return 0;
>
> }
>
> The output is
> 2 2
>
> Shouldn't the second expression be -2 rather than 2? I'm confused.
> Your insights pls. Thanks!

Shouldn't it be i+=j and i-=j?.. Then you'll get 2 -2.

Eric Sosman

9/10/2011 8:43:00 PM

0

On 9/10/2011 3:59 PM, China Blue Corn Chips wrote:
> In article<8787e0b5-b4c3-463f-bd9a-6ffc30034950@x29g2000prh.googlegroups.com>,
> Mazen<neurohacks@gmail.com> wrote:
>[...]
>> printf("%d %d\n", i=+j, i=-j);
>> [...]
>> The output is
>> 2 2
>>
>> Shouldn't the second expression be -2 rather than 2? I'm confused.
>> Your insights pls. Thanks!
>
> The order of evaluation of function arguments is left to the implementation.

It's more serious than that: The behavior is undefined. The
line in question tries to assign to `i' twice without an intervening
sequence point, and the C language makes no promises whatsoever about
what might happen in consequence.

C has two distinct uses for the comma: as an operator, and as
a separator. The comma operator involves a defined order and a
sequence point: `f = x,y' means "first evaluate x and ignore the
value, sequence point, then evaluate y and yield its value, that
value is assigned to f." The comma separator just separates the
elements of a list, without implying any kind of order and without
imposing sequence points. (Unfortunately, the two uses look
distressingly similar.)

In the offending line above, both commas are separators rather
than operators, so no sequence points divide the argument evaluations
from each other. In particular, the two assignments to `i' are not
so divided, hence the undefined behavior.

--
Eric Sosman
esosman@ieee-dot-org.invalid

Eric Sosman

9/10/2011 8:49:00 PM

0

On 9/10/2011 4:31 PM, arni wrote:
> On Sep 10, 10:36 pm, Mazen<neuroha...@gmail.com> wrote:
>> [...]
>> printf("%d %d\n", i=+j, i=-j);
>> [...]
>> return 0;
> [...]
> Shouldn't it be i+=j and i-=j?.. Then you'll get 2 -2.

Or not: The behavior would still be undefined, and for the
same reason as before.

--
Eric Sosman
esosman@ieee-dot-org.invalid

arni

9/10/2011 9:14:00 PM

0

On Sep 10, 11:49 pm, Eric Sosman <esos...@ieee-dot-org.invalid> wrote:
> On 9/10/2011 4:31 PM, arni wrote:
>
> > On Sep 10, 10:36 pm, Mazen<neuroha...@gmail.com>  wrote:
> >> [...]
> >>    printf("%d %d\n", i=+j, i=-j);
> >> [...]
> >>    return 0;
> > [...]
> > Shouldn't it be i+=j and i-=j?.. Then you'll get 2 -2.
>
>      Or not: The behavior would still be undefined, and for the
> same reason as before.
>
> --
> Eric Sosman
> esos...@ieee-dot-org.invalid

Depends on compiler/optimizer implementation. Anyway, writing code
like that is a very bad practice, you can not be sure what's going to
happen in the end :)

Morris Keesan

9/10/2011 9:16:00 PM

0

On Sat, 10 Sep 2011 16:31:33 -0400, arni <arnmin@gmail.com> wrote:

> On Sep 10, 10:36 pm, Mazen <neuroha...@gmail.com> wrote:
>> Hello,
>>
>> Following is a simple program:
>>
>> #include <stdio.h>
>>
>> int main(void) {
>>   int i = 0, j, k;
>>   j = k = 2;
>>
>>   printf("%d %d\n", i=+j, i=-j);
>>
>>   return 0;
>>
>> }
>>
>> The output is
>> 2 2
>>
>> Shouldn't the second expression be -2 rather than 2? I'm confused.
>> Your insights pls. Thanks!
>
> Shouldn't it be i+=j and i-=j?.. Then you'll get 2 -2.

No. If modifying i twice in the argument list weren't undefined,
so that one assignment to i and the evaluation of the corresponding
function argument were guaranteed to be complete before the next
argument was evaluated, printf("%d %d\n", i += j, i -= j) would produce
either "2 0" or "0 -2", depending on the order in which the arguments
are evaluated, which is unspecified (not undefined). The poorly-spaced
code seems to have been intended as printf("%d %d\n", i = +j, i = -j);
--
Morris Keesan -- mkeesan@post.harvard.edu

Eric Sosman

9/10/2011 9:26:00 PM

0

On 9/10/2011 5:13 PM, arni wrote:
> On Sep 10, 11:49 pm, Eric Sosman<esos...@ieee-dot-org.invalid> wrote:
>> On 9/10/2011 4:31 PM, arni wrote:
>>
>>> On Sep 10, 10:36 pm, Mazen<neuroha...@gmail.com> wrote:
>>>> [...]
>>>> printf("%d %d\n", i=+j, i=-j);
>>>> [...]
>>>> return 0;
>>> [...]
>>> Shouldn't it be i+=j and i-=j?.. Then you'll get 2 -2.
>>
>> Or not: The behavior would still be undefined, and for the
>> same reason as before.
>
> Depends on compiler/optimizer implementation.

The C language is defined by an International Standard, not by
the quirks of any individual compiler. The Standard does not define
any specific behavior for the offending line, nor even any limits on
the possible behaviors.

In particular, there's no guarantee that "you'll get 2 -2."

A particular implementation is free to add (or not) its own
definitions to cover cases the Standard leaves undefined -- but
then you're no longer talking about "C," but about "Frobozz Magic
C Version 4.2 optimization level 3 with #pragma DWIM in effect."

> Anyway, writing code
> like that is a very bad practice, you can not be sure what's going to
> happen in the end :)

Exactly: "What's going to happen" is not defined by the C language.

--
Eric Sosman
esosman@ieee-dot-org.invalid

Bartc

9/10/2011 10:21:00 PM

0

"Mazen" <neurohacks@gmail.com> wrote in message
news:8787e0b5-b4c3-463f-bd9a-6ffc30034950@x29g2000prh.googlegroups.com...

> #include <stdio.h>
>
> int main(void) {
> int i = 0, j, k;
> j = k = 2;
>
> printf("%d %d\n", i=+j, i=-j);
>
> return 0;
> }
>
> The output is
> 2 2
>
> Shouldn't the second expression be -2 rather than 2? I'm confused.

It *is* unintuitive. But printf() is a function, and sometimes the
parameters are evaluated in a funny order:

#include <stdio.h>

int next(void){static int a=0; return ++a;}

int main(void){
printf("%d %d %d\n",next(),next(),next());
}

gives 1 2 3 on one compiler, and 3 2 1 on another (and doubtless some
compiler might give 3 1 2!).

Changing main() to resemble your code:

int main(void){
int i;
printf("%d %d %d",i=next(),i=next(),i=next());
}

Now I get results on 1 2 3, 3 3 3, and 3 2 1 on three different compilers!

For guaranteed results, you need to use a separate printf() call for each
term.

--
Bartc

Mazen

9/11/2011 12:52:00 AM

0

Thanks, Eric. So, how can one achieve the desired result and guarantee a defined behavior?

Mazen

9/11/2011 12:59:00 AM

0

On Sep 10, 2:26 pm, Eric Sosman <esos...@ieee-dot-org.invalid> wrote:
> On 9/10/2011 5:13 PM, arni wrote:
>
> > On Sep 10, 11:49 pm, Eric Sosman<esos...@ieee-dot-org.invalid>  wrote:
> >> On 9/10/2011 4:31 PM, arni wrote:
>
> >>> On Sep 10, 10:36 pm, Mazen<neuroha...@gmail.com>    wrote:
> >>>> [...]
> >>>>     printf("%d %d\n", i=+j, i=-j);
> >>>> [...]
> >>>>     return 0;
> >>> [...]
> >>> Shouldn't it be i+=j and i-=j?.. Then you'll get 2 -2.
>
> >>       Or not: The behavior would still be undefined, and for the
> >> same reason as before.
>
> > Depends on compiler/optimizer implementation.
>
>      The C language is defined by an International Standard, not by
> the quirks of any individual compiler.  The Standard does not define
> any specific behavior for the offending line, nor even any limits on
> the possible behaviors.
>
>      In particular, there's no guarantee that "you'll get 2 -2."
>
>      A particular implementation is free to add (or not) its own
> definitions to cover cases the Standard leaves undefined -- but
> then you're no longer talking about "C," but about "Frobozz Magic
> C Version 4.2 optimization level 3 with #pragma DWIM in effect."
>
> > Anyway, writing code
> > like that is a very bad practice, you can not be sure what's going to
> > happen in the end :)
>
>      Exactly: "What's going to happen" is not defined by the C language.
>
> --
> Eric Sosman
> esos...@ieee-dot-org.invalid

I have learned the attempting to assign a value to a variable and
fetching the value of it in the same expression will produce an
undefined behaviour. What are some of the other cases that produce
undefined behaviour? This is interesting!

Thanks!

Joe Pfeiffer

9/11/2011 2:39:00 AM

0

Mazen <neurohacks@gmail.com> writes:

> Thanks, Eric. So, how can one achieve the desired result and guarantee
> a defined behavior?

In short, "don't do that".

Getting your desired result depends (of course) on what result you
desired. Assuming your printf() was meant to be

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

(so you were using an unnecessary '+', as opposed to using the old =+
syntax for += ), then even if it were defined it would be silly. Why
exactly did you assign a value to i, and then assign another value to
it?

If your intent was to print the value of j, print the value of -j, and
set i to -j, here's something that will do it:

printf("%d %d\n", j, i = -j);

If your intent was something else, well, you'd have to do something
else.