4

I am working in C++ (not C++/CLI) in Visual Studio 2012.

I don't understand why this code works, I would have expected it to fail at compilation time, but it doesn't even fail at runtime:

double MyClass::MyMethod() const
{
    //some code here        
    return (10, 20, 30, 40);
}

I produced this code by mistake, wasn't on purpose, I noticed the mistake when I was running my Unit Tests. And I am surprised it works. When I run it, it returns 40, the last number on the list.

Can someone explain me what this syntax means and why it works?

Shafik Yaghmour
  • 154,301
  • 39
  • 440
  • 740
Dzyann
  • 5,062
  • 11
  • 63
  • 95
  • I am curious what code was supposed to be there? A function call? – Shafik Yaghmour Nov 15 '13 at 13:03
  • @ShafikYaghmour, lol yes! I have code in C# that I am passing to C++ and it seems I missed to write the function name when I was creating everything, and the values were not const integers like that, they were variables, but for the question they were good enough. :) Thanks for your answer! – Dzyann Nov 15 '13 at 13:28

4 Answers4

9

This is using the comma operator which will evaluate each expression from left to right but only return the last. If we look at the draft C++ standard section 5.18 Comma operator it says:

A pair of expressions separated by a comma is evaluated left-to-right; the left expression is a discarded value expression (Clause 5).83 Every value computation and side effect associated with the left expression is sequenced before every value computation and side effect associated with the right expression.

the linked article gives the most common use as:

allow multiple assignment statements without using a block statement, primarily in the initialization and the increment expressions of a for loop.

and this previous thread Uses of C comma operator has some really interesting examples of how people use the comma operator if you are really curious.

Enabling warning which is always a good idea may have helped you out here, in gcc using -Wall I see the following warning:

warning: left operand of comma operator has no effect [-Wunused-value]
  return (10, 20, 30, 40);
              ^

and then two more of those.

Community
  • 1
  • 1
Shafik Yaghmour
  • 154,301
  • 39
  • 440
  • 740
  • Very interesting! When I saw that code, I didn't realize it was using the comma operator (probably because in C# that wouldn't work), I searched on internet and of course I couldn't find anyone asking the same thing than me. Here there is another interesting question related to the use of the comma operator and its precedence http://stackoverflow.com/questions/54142/how-does-the-comma-operator-work I find interesting that doing return 10, 20, 30, 40 would work too, but It would return 10 – Dzyann Nov 15 '13 at 13:33
  • Interestingly enough, I have warnings enabled, but Visual Studio doesn't show a warning in that line. – Dzyann Nov 15 '13 at 13:45
  • @Dzyann ok, I get [a warning](http://rextester.com/ZUZB34026) if I use `/Wall` but if you include any headers it will generate an unusable amount of warnings so it is useless. That is really silly. – Shafik Yaghmour Nov 15 '13 at 13:52
  • Yes you are right, I had enabled exceptions only up to W3 (Default of Visual studio apparently), I get over 6k warnings, most come from files from the standard library. Not very useful. – Dzyann Nov 15 '13 at 14:09
  • 2
    /Wall is generally not useful, because it literally enables all of the warnings (on some other compilers, /Wall only enables "useful" warnings; for Visual C++, /W4 does this). You should use /W4, then enable specific warnings that you care about. You can enable individual warnings using [the /w option](http://msdn.microsoft.com/en-us/library/thxezb7y.aspx), e.g. cl /W4 /w44548 will enable warning 4548 (the one you're looking for) at warning level 4. – James McNellis Nov 15 '13 at 17:05
  • @JamesMcNellis ok, I could not figure that out, your suggestion works for me, thanks. Although, a lot of those warnings turned off by default seem pretty useful, especially for less experienced users who may not realize some of those warnings are good to have on. – Shafik Yaghmour Nov 15 '13 at 17:38
  • @Dzyann James was kind enough to chime in on the warning flags. – Shafik Yaghmour Nov 15 '13 at 17:38
  • @ShafikYaghmour: There are many factors that go into the decision as to whether a warning is enabled by default or not. We're always open to suggestions though; feel free to open an issue on [Microsoft Connect](http://connect.microsoft.com/visualstudio) if you think this warning should not be off-by-default. – James McNellis Nov 15 '13 at 17:50
4

The comma operator is a 'sequence point' in C++, often used to initialise multiple variables in for loops.

So the code is evaluating a series of integers, one at a time, as single expressions. The last of these is the returned value, and the return statement as a whole is equivalent to simply return (40);

codedstructure
  • 796
  • 7
  • 16
  • 2
    C++11 has [done away](http://stackoverflow.com/a/4183735/183120) with the idea of sequence points. – legends2k Nov 15 '13 at 12:46
  • 1
    @legends2k: But not the idea of sequencing, and it still makes sense to talk about "sequence points" within a thread even if the standard uses a more long-winded way of saying the same thing. – Mike Seymour Nov 15 '13 at 13:20
  • @MikeSeymour Agreed, that was just to nitpick on the term used and also to spread the word about the new terminology; conceptually it still exists. – legends2k Nov 15 '13 at 13:54
1

the expression (10, 20, 30, 40) is actually a series of 4 expressions separated by , You can use , to separate multiple expressions and the result is the evaluation of the last one.

Raxvan
  • 6,257
  • 2
  • 25
  • 46
1

You have used the , i.e. comma operator

return () is valid.

and so is return (/*valid evaluation*/)

Comma operator returns the last value i.e 40

Community
  • 1
  • 1
Suvarna Pattayil
  • 5,136
  • 5
  • 32
  • 59