Reputation:
I'm very beginner in C++ and I'm currently reading a book to get better in it. While reading a section about C++'s only ternary operator, I played around some code and got a question:
So, when I do this:
std::cout << "Hello ", "Mars";
I get a warning:
warning: right operand of comma operator has no effect [-Wunused-value]
And when I do this:
std::cout << (5 > 4 ? "Hello ", "Mars" : "Bye ", "World");
?:
I get:
warning: left operand of comma operator has no effect [-Wunused-value]
?:
I get:
warning: left operand of comma operator has no effect [-Wunused-value]
So my question is, why do I get the first warning for the second operand of ?:
, while I get the second warning for the third operand of ?:
?
Upvotes: 0
Views: 3212
Reputation: 122238
From cppreference:
In a comma expression E1, E2, the expression E1 is evaluated, its result is discarded (although if it has class type, it won't be destroyed until the end of the containing full expression), and its side effects are completed before evaluation of the expression E2 begins (note that a user-defined operator, cannot guarantee sequencing) (until C++17).
It is the result of left operand that is discarded. However, if you consider operator precedence
, where the comma operator is always last, then
std::cout << "Hello ", "Mars";
is the same as
(std::cout << "Hello ") , ( "Mars" ) ;
and the compiler is trying to be clever. This
std::cout << "Hello "
does have an effect even if you ignore the returned value. Note that operator<<
returns a reference to the stream and you typically ignore that value. Hence, discarding it via the comma operator does not prevent it to print something on the screen.
On the other hand
"Mars";
as a statement has no effect and that is what the compiler is trying to tell in that case.
Upvotes: 4
Reputation: 32732
It's because of how you're using them. If you'd written
"Mars", std::cout<<"Hello ";
you'd get the "left operand has no effect" warning. If you'd have assigned your expression to a variable
const char *msg = std::cout << "Hello ", "Mars";
you wouldn't get any warnings. When this code is executed, "Hello " would be sent to cout
, and msg
would be pointing to "Mars".
For the ternary operator, the right operand of the comma operator is the result of the operator, which is the expression value for the ternary operator. Your example is the same as if you'd have written
std::cout << (5 > 4 ? "Mars" : "World");
Upvotes: 3