comma operator

• (2 Pages)
• 1
• 2

16 Replies - 2318 Views - Last Post: 09 September 2011 - 12:31 PMRate Topic: //<![CDATA[ rating = new ipb.rating( 'topic_rate_', { url: 'http://www.dreamincode.net/forums/index.php?app=forums&module=ajax&section=topics&do=rateTopic&t=177775&amp;s=8b4f85665a40ce42f00497588ac1a598&md5check=' + ipb.vars['secure_hash'], cur_rating: 0, rated: 0, allow_rate: 0, multi_rate: 1, show_rate_text: true } ); //]]>

#1 paps3535

Reputation: 0
• Posts: 11
• Joined: 11-November 09

comma operator

Posted 14 June 2010 - 11:56 PM

```void main()
{
int n=10;
printf("%d \n %d",++n,n++);
}
```

o/p; 12 10

why so?..I have been thru different webpages..but still not got d clear idea...can sumone xplain it?..

This post has been edited by NickDMax: 15 June 2010 - 06:21 AM
Reason for edit:: added code tags: [code] -- paste your code here -- [/code]

Is This A Good Question/Topic? 0

Replies To: comma operator

#2 Munawwar

• D.I.C Regular

Reputation: 161
• Posts: 457
• Joined: 20-January 10

Re: comma operator

Posted 15 June 2010 - 12:20 AM

Because operators are evaluated in stack order (right to left). So n++ is evaluated before ++n.
n++ is 10. n will increment only on encountering ; or , OR if a prefixed increment operation is done on n (that is ++n).

EDIT:
Try this
```int m = ++n + n++;
printf("%d",m);

```

you will may get output as 22

Now try this
```n = ++n + n++;
printf("%d",n);

```

I got the output as 23, on GCC 4.4. Which is not what I expected. Can anyone explain that?

This post has been edited by Munawwar: 15 June 2010 - 08:36 AM

#3 Banfa

Reputation: 83
• Posts: 109
• Joined: 07-June 10

Re: comma operator

Posted 15 June 2010 - 05:52 AM

All the code posted in this thread so far exhibits undefined behaviour.

When undefined behaviour is invoked the compiler, and the code it produces, can do anything, literally, including giving you the results you expect until a critical moment in time and then failing for no-other apparent reason or (as the comp.lang.c like to say) make demons fly out of your nose.

Specifically all these code examples break the edict against accessing a variable more than once between sequence points where any one of those accesses is to change the value of the variable.

Oh and btw the order that the parameters to a function are evaluated in is implementation defined.

This post has been edited by Banfa: 15 June 2010 - 05:52 AM

#4 NickDMax

Reputation: 2209
• Posts: 9,183
• Joined: 18-February 07

Re: comma operator

Posted 15 June 2010 - 06:30 AM

as Banfa has accurately reported -- one can not use the pre/post increment operators on the same variable in the same line of code, to do so is undefined (meaning anything could happen and it would be "correct") and there is little point trying to explain why you get the answer that you do, because it is NOT C++ and would only be supposition based upon that particular compiler in the particular bit of code; because it is undefined, the compiler MAY (and probably will) evaluate it differently in different situations.

Alos -- this has nothing to do with the comma operator. the commas in function calls are not "comma operators" but "parameter seperators" -- the compiler can evaluate the expressions used as parameters in ANYWAY IT SEES FIT. i.e. the order that function parameters are evaluated is left undefined as well. So again the compiler can evaluate them in any order it chooses, and optimizing compilers will often surprise you and evaluate them is unexpected ways!!! That is why things like this are also undefined:

```a = 10;
printf("%d %d\n", a = 20, a); //undefined behavior
```

One compiler may give you 20 10 and another compiler may give you 20 20 -- and they would BOTH be correct! You the programmer would be wrong, because you have written a program with undefined behavior.

#5 NickDMax

Reputation: 2209
• Posts: 9,183
• Joined: 18-February 07

Re: comma operator

Posted 15 June 2010 - 06:45 AM

So I ran the original code though 4 different compilers:
```#include <stdio.h>

int main() {
int n=10;
printf("%d \t %d",++n,n++);
return 0;
}
```

Borland 5.5: 12 10
VC 2010:11 10
MinGW:12 10
Pelles C:12 10

is VC 2010 broken? No, it is optimizing. Do not use undefined behavior because the results may surprise you optimizing compilers OFTEN use "features" available to them (like an undefined order of evaluation) to optimize execution.

#6 Munawwar

• D.I.C Regular

Reputation: 161
• Posts: 457
• Joined: 20-January 10

Re: comma operator

Posted 15 June 2010 - 06:54 AM

Right. I was talking with my 'old' experience with borland 3.1.
To test Banfa's claim I ran two test snippets on 3 different compilers.

Test 1:
```int n=10;
int m = n++ + ++n + n++;
cout<<m;

```

gcc 4.4: 33
VC2008: 33
Ancient compiler, Borland 3.1: 34

Test 2:
```int n=10;
int m = n++ + ++n + n++ + ++n;
cout<<m;

```

gcc: 45
VC2008: 48
Borland 3.1: 48

Nice, I learn't something new today!

This post has been edited by Munawwar: 15 June 2010 - 06:56 AM

#7 Banfa

Reputation: 83
• Posts: 109
• Joined: 07-June 10

Re: comma operator

Posted 15 June 2010 - 07:36 AM

@Munawwar um yes but what we want to know is did any demons fly out of your nose?

#8 Munawwar

• D.I.C Regular

Reputation: 161
• Posts: 457
• Joined: 20-January 10

Re: comma operator

Posted 15 June 2010 - 08:44 AM

In my school days we were taught that it was evaluated from right to left, but never did my teacher mention that this is undefined nor did he mention that this is specific to borland 3.1.
"et tu, teacher"

#9 Banfa

Reputation: 83
• Posts: 109
• Joined: 07-June 10

Re: comma operator

Posted 15 June 2010 - 08:56 AM

He was suffering from a common problem. Working out what happens on the implementation you are using and assuming all implementations do that rather than reading the standard (or a good book) and finding out what the actual behaviour is.

#10 NickDMax

Reputation: 2209
• Posts: 9,183
• Joined: 18-February 07

Re: comma operator

Posted 15 June 2010 - 09:22 AM

Munawwar -- Actually this is a common thing in schools and even on interviews. People will come up with questions such as:

what will be the output of cout << ++n+n++; or cout << n+++++n; as though this were some kind of test of your understanding of pre and post increment. So far no one has ever come back and told us what happens when you tell your professor: "that is undefined"

A good read is to glance over the C-FAQ from comp.lang.c you might even find a few that you *thought* you knew the answer to.

For example I might not have really looked to hard at this: i = i++; even though its behavior is undefined (double assignment).

#11 Salem_c

• void main'ers are DOOMED

Reputation: 1418
• Posts: 2,681
• Joined: 30-May 10

Re: comma operator

Posted 15 June 2010 - 09:28 AM

POPULAR

To expand on earlier posts, I'm reposting something I wrote some time ago for another forum.

- Changing compiler options changes things.
- Changing compiler changes things.
- Even changing the compiler version changes things!.
In short - "DON'T GO THERE!"

This is a catalogue of some experiments showing unspecified behaviour and undefined behaviour.

This was inspired by yet another long bout of explanation in a recent thread, so I thought it was time to dust off a bunch of compilers, and compare.

This is the test code.
```#include <stdio.h>

int f1 ( void ) {
printf( "f1 called = 1\n" );
return 1;
}
int f2 ( void ) {
printf( "f2 called = 2\n" );
return 2;
}
int f3 ( void ) {
printf( "f3 called = 3\n" );
return 3;
}
int f4 ( void ) {
printf( "f4 called = 4\n" );
return 4;
}
int f5 ( void ) {
printf( "f5 called = 5\n" );
return 5;
}

/* Although * happens before +, there is NO guarantee that */
/* f1() will always be called after f2() and f3() */
/* http://c-faq.com/expr/precvsooe.html */
void test1 ( void ) {
int result;
printf( "Precedence is not the same as sub-expression evaluation order\n" );
result = f1() + f2() * f3() - f4() / f5();
printf( "Result=%d\n", result );
printf( "inline=%d\n", f1() + f2() * f3() - f4() / f5() );
}

/* The nature of 'before' and 'after' is poorly understood */
/* http://c-faq.com/expr/evalorder2.html */
void test2 ( void ) {
int i = 3, j = 3;
int r1 = ++i * i++;
printf( "Multiple side effects are undefined\n" );
printf( "R1=%d, i=%d\n", r1, i );
printf( "R2=%d, j=%d\n", ++j * j++, j );
}

int main ( ) {
test1();
test2();
return 0;
}
```

test1() gives a well-defined answer, as one would expect.
What is unspecified however, is the order in which f1() to f5() are called.
That is, the order of the printf statements varies (quite amazingly).

test2() is just broken code with no redeeming features. Yet despite this, people often claim they know how the result is worked out.
One set of results will however make you think about it!

All tests were done using XP as the host OS, with the exception of the gcc test, which was done under Ubuntu.

The only compiler flags used were to test the effect of optimisation.
For most of the Windows compilers, this is basically a choice between "optimise for space" or "optimise for speed".

The compiler results are presented in approximately alphabetical order.

Borland C++ Compiler 5.5, With Command Line Tools, Version 5.5.1
No Optimisation
```Precedence is not the same as sub-expression evaluation order
f2 called = 2
f3 called = 3
f1 called = 1
f4 called = 4
f5 called = 5
Result=7
f2 called = 2
f3 called = 3
f1 called = 1
f4 called = 4
f5 called = 5
inline=7
Multiple side effects are undefined
R1=16, i=5
R2=16, j=3

```

Optimisation level O1
```Precedence is not the same as sub-expression evaluation order
f2 called = 2
f3 called = 3
f1 called = 1
f4 called = 4
f5 called = 5
Result=7
f2 called = 2
f3 called = 3
f1 called = 1
f4 called = 4
f5 called = 5
inline=7
Multiple side effects are undefined
R1=16, i=5
R2=16, j=3
```

Optimisation level O2
```Precedence is not the same as sub-expression evaluation order
f2 called = 2
f3 called = 3
f1 called = 1
f4 called = 4
f5 called = 5
Result=7
f2 called = 2
f3 called = 3
f1 called = 1
f4 called = 4
f5 called = 5
inline=7
Multiple side effects are undefined
R1=16, i=5
R2=16, j=3
```

Not a lot of surprises here. The result is consistent across all three compilations and the function call order reflects what one would expect from looking at the code.

Digital Mars Compiler Version 8.42n
No Optimisation
```Precedence is not the same as sub-expression evaluation order
f1 called = 1
f2 called = 2
f3 called = 3
f4 called = 4
f5 called = 5
Result=7
f1 called = 1
f2 called = 2
f3 called = 3
f4 called = 4
f5 called = 5
inline=7
Multiple side effects are undefined
R1=16, i=5
R2=16, j=3
```

Optimisation level O1
```Precedence is not the same as sub-expression evaluation order
f1 called = 1
f2 called = 2
f3 called = 3
f4 called = 4
f5 called = 5
Result=7
f1 called = 1
f2 called = 2
f3 called = 3
f4 called = 4
f5 called = 5
inline=7
Multiple side effects are undefined
R1=16, i=5
R2=16, j=3
```

Optimisation level O2
```Precedence is not the same as sub-expression evaluation order
f1 called = 1
f2 called = 2
f3 called = 3
f4 called = 4
f5 called = 5
Result=7
f1 called = 1
f2 called = 2
f3 called = 3
f4 called = 4
f5 called = 5
inline=7
Multiple side effects are undefined
R1=16, i=5
R2=16, j=3
```

A good level of consistency, but now the order is essentially L->R as the code is read.

gcc (GCC) 4.2.4 (Ubuntu 4.2.4-1ubuntu4)
No Optimisation
```Precedence is not the same as sub-expression evaluation order
f1 called = 1
f2 called = 2
f3 called = 3
f4 called = 4
f5 called = 5
Result=7
f1 called = 1
f2 called = 2
f3 called = 3
f4 called = 4
f5 called = 5
inline=7
Multiple side effects are undefined
R1=16, i=5
R2=16, j=5
```

Optimisation level O2
```Precedence is not the same as sub-expression evaluation order
f1 called = 1
f2 called = 2
f3 called = 3
f4 called = 4
f5 called = 5
Result=7
f1 called = 1
f2 called = 2
f3 called = 3
f4 called = 4
f5 called = 5
inline=7
Multiple side effects are undefined
R1=16, i=5
R2=16, j=5
```

Like DMC, GCC evaluates left to right (in this test).
But the side-effect ridden evaluation of j now results in 5 and not 3.

lcc-win32 version 3.8. Compilation date: Mar 24 2008 11:52:21
No Optimisation
```Precedence is not the same as sub-expression evaluation order
f1 called = 1
f2 called = 2
f3 called = 3
f4 called = 4
f5 called = 5
Result=7
f1 called = 1
f2 called = 2
f3 called = 3
f4 called = 4
f5 called = 5
inline=7
Multiple side effects are undefined
R1=16, i=5
R2=16, j=3
```

Optimisation enabled
```Precedence is not the same as sub-expression evaluation order
f1 called = 1
f2 called = 2
f3 called = 3
f4 called = 4
f5 called = 5
Result=7
f1 called = 1
f2 called = 2
f3 called = 3
f4 called = 4
f5 called = 5
inline=7
Multiple side effects are undefined
R1=16, i=5
R2=16, j=3
```

No great surprise here.

VC6 - Microsoft ® 32-bit C/C++ Optimizing Compiler Version 12.00.8804
No Optimisation
```Precedence is not the same as sub-expression evaluation order
f1 called = 1
f2 called = 2
f3 called = 3
f4 called = 4
f5 called = 5
Result=7
f1 called = 1
f2 called = 2
f3 called = 3
f4 called = 4
f5 called = 5
inline=7
Multiple side effects are undefined
R1=16, i=5
R2=16, j=3
```

Optimisation level O1
```Precedence is not the same as sub-expression evaluation order
f5 called = 5
f4 called = 4
f3 called = 3
f2 called = 2
f1 called = 1
Result=7
f5 called = 5
f4 called = 4
f3 called = 3
f2 called = 2
f1 called = 1
inline=7
Multiple side effects are undefined
R1=16, i=5
R2=16, j=5
```

Optimisation level O2
```Precedence is not the same as sub-expression evaluation order
f5 called = 5
f4 called = 4
f3 called = 3
f2 called = 2
f1 called = 1
Result=7
f5 called = 5
f4 called = 4
f3 called = 3
f2 called = 2
f1 called = 1
inline=7
Multiple side effects are undefined
R1=16, i=5
R2=16, j=5
```

Totally crazy!
Turning on the optimiser calls the functions in the REVERSE order.
And the grossly undefined evaluation of j in test2 returns a different answer to the unoptimised code.
Is the compiler broke? Nope, the code is just rubbish.

VS2008 - Microsoft ® 32-bit C/C++ Optimizing Compiler Version 15.00.21022.08
No Optimisation
```Precedence is not the same as sub-expression evaluation order
f1 called = 1
f2 called = 2
f3 called = 3
f4 called = 4
f5 called = 5
Result=7
f1 called = 1
f2 called = 2
f3 called = 3
f4 called = 4
f5 called = 5
inline=7
Multiple side effects are undefined
R1=16, i=5
R2=16, j=4
```

Optimisation level O1
```Precedence is not the same as sub-expression evaluation order
f4 called = 4
f5 called = 5
f2 called = 2
f3 called = 3
f1 called = 1
Result=7
f4 called = 4
f5 called = 5
f2 called = 2
f3 called = 3
f1 called = 1
inline=7
Multiple side effects are undefined
R1=16, i=5
R2=16, j=4
```

Optimisation level O2
```Precedence is not the same as sub-expression evaluation order
f1 called = 1
f2 called = 2
f3 called = 3
f4 called = 4
f5 called = 5
Result=7
f1 called = 1
f2 called = 2
f3 called = 3
f4 called = 4
f5 called = 5
inline=7
Multiple side effects are undefined
R1=16, i=5
R2=16, j=4
```

Now we're cooking!
Not only do you get a different order of function calls when turning on optimisation, the order is no longer the same between optimisation levels!.
And let's give a big hand to the appearance of j=4 for the first time in our results.

Open Watcom C/C++ CL Clone for 386 Version 1.7
No Optimisation
```Precedence is not the same as sub-expression evaluation order
f2 called = 2
f3 called = 3
f1 called = 1
f4 called = 4
f5 called = 5
Result=7
f2 called = 2
f3 called = 3
f1 called = 1
f4 called = 4
f5 called = 5
inline=7
Multiple side effects are undefined
R1=20, i=5
R2=20, j=3
```

Optimisation level O1
```Precedence is not the same as sub-expression evaluation order
f2 called = 2
f3 called = 3
f1 called = 1
f4 called = 4
f5 called = 5
Result=7
f2 called = 2
f3 called = 3
f1 called = 1
f4 called = 4
f5 called = 5
inline=7
Multiple side effects are undefined
R1=20, i=5
R2=20, j=3
```

Optimisation level O2
```Precedence is not the same as sub-expression evaluation order
f2 called = 2
f3 called = 3
f1 called = 1
f4 called = 4
f5 called = 5
Result=7
f2 called = 2
f3 called = 3
f1 called = 1
f4 called = 4
f5 called = 5
inline=7
Multiple side effects are undefined
R1=20, i=5
R2=20, j=3
```

More variation - where will it stop?
The functions are back to being called in what seems to be precedence order.
But wait, R1=R2=20
Everything else up to now has been R1=R2=16

This post has been edited by Salem_c: 15 June 2010 - 09:29 AM

#12 NickDMax

Reputation: 2209
• Posts: 9,183
• Joined: 18-February 07

Re: comma operator

Posted 15 June 2010 - 09:32 AM

excellent example!

#13 timetraveller

Reputation: -22
• Posts: 10
• Joined: 09-September 11

Re: comma operator

Posted 09 September 2011 - 11:04 AM

hey dude its pretty simple.. i dunno what banfa or the rest of the guyz have been smoking on! But here's my explaination

This post has been edited by timetraveller: 09 September 2011 - 11:08 AM

#14 NickDMax

Reputation: 2209
• Posts: 9,183
• Joined: 18-February 07

Re: comma operator

Posted 09 September 2011 - 11:09 AM

The operations is undefined -- i.e. the compiler can do anything it wants, the compiler could format the hard drive and it would be perfectly legal operation. Just because YOUR compiler SEEMS to behave the way you THINK it does, does not change the fact that the operation is undefined in C++.

Different compilers (yes even the same compiler with different settings) may produce different results.

#15 timetraveller

Reputation: -22
• Posts: 10
• Joined: 09-September 11

Re: comma operator

Posted 09 September 2011 - 11:23 AM

NickDMax, on 09 September 2011 - 11:09 AM, said:

The operations is undefined -- i.e. the compiler can do anything it wants, the compiler could format the hard drive and it would be perfectly legal operation. Just because YOUR compiler SEEMS to behave the way you THINK it does, does not change the fact that the operation is undefined in C++.

Different compilers (yes even the same compiler with different settings) may produce different results.

maybe u need to study about compilers more better sir. I'm 19 and I'm sure i know how they work. Your compiler (if its official and popular) DOES NOT do something stupid like formatting C unless u program a code to do so. Maybe u need to learn what compilers are meant for.. use debugger to reverse the code. So, compiler is just a program that calls another set of programs in a sequence. And those called programs happen to be translators which keep translating the code until it ends up in 0s and 1s(also called binary). And that enters the processor logic gates and executes as per the CPU's instructions. The registers work continuously and when the output is generated. Sometimes send to the output devices.. and can even do nothing! It depends on ur program. And besides.. If ur compiler erases ur HDD then u can easily sue the company..!

I think its time to get the demons out of your nose!

P.S. I take classes for my seniors in college. This one is the easiest problem we solved last week

This post has been edited by timetraveller: 09 September 2011 - 11:25 AM