Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

comma operator in c++ doesn't evaluate second expression

I wrote the following code:

#include <iostream>
using namespace std;

int f()
{
    cout << "f()" << endl;
    return 3;
}

int v()
{
    cout << "v()" << endl;
    return 4;
}

int main()
{
    int m = f(),v();
    cout << m << endl;
    return 0;
}

I expected it to print:

f()
v()
3

compiling with g++ -O0 test.cpp -o test.out and running results:

f()
3

Why the call to v is omitted? (this can't be do to optimization, because I added the flag -O0)

like image 877
elyashiv Avatar asked Nov 10 '13 07:11

elyashiv


People also ask

What does the comma operator do in C?

The comma operator in c comes with the lowest precedence in the C language. The comma operator is basically a binary operator that initially operates the first available operand, discards the obtained result from it, evaluates the operands present after this, and then returns the result/value accordingly.

Can we use comma in if condition?

Use a comma after the if-clause when the if-clause precedes the main clause. If I'd had time, I would have cleaned the house. If the main clause precedes the if-clause, no punctuation is necessary. I would have cleaned the house if I'd had time.

How is comma operator useful in a for loop in C?

The comma operator will always yield the last value in the comma separated list. Basically it's a binary operator that evaluates the left hand value but discards it, then evaluates the right hand value and returns it. If you chain multiple of these they will eventually yield the last value in the chain.

How is comma operator useful in a for loop?

To include more than one statement in the initialization and iteration portions of the for loop we can use comma operator. The loop is controlled by the interaction of two variables. Java allows two or more variables to control a for loop.


2 Answers

int m = f(),v(); 

This statement executes f() and assign return value to m, then declare function v() which return int type. int v(); also known as most vexing parse.

To achieve your comma operator test, try:

int m;
m = f(),v();
cout << m << endl;

see live sample.

like image 70
billz Avatar answered Oct 15 '22 00:10

billz


The following variation of your code demonstrates what this is doing:

http://ideone.com/GBae0p

#include <iostream>

int f() { std::cout << "f()" << std::endl; return 1; }

int main() {
   int t = f(), v();
   std::cout << t << std::endl;
   return 0;
}

This compiles without error, even though we don't have a "v()".

The comma operator is splitting this line

   int t = f(), v();

into

   int t = f();
   int v();

The second line is a function prototype which declares that there will be a function, int v(), which takes no parameters and returns an int.

It doesn't call it, it just pre-declares it - incase the compiler encounters a call it to it before it is actually defined - because the body is an empty statement (;). The compiler assumes we will implement it later or in a different compilation unit.

Because this commonly confuses experience and new programmers alike, because it is introduced by C++ allowing you to put function prototypes inside function bodies, this is called the most vexing parse.

like image 35
kfsone Avatar answered Oct 15 '22 01:10

kfsone