z3moon
z3moon

Reputation: 149

About shift operator trick in C++?

When I was reading the code in Google Protocol Buffers, I found confused code as follows.

1 < 2 ? (void)0 : cout << "hi" << endl;

The point is that the string "hi' will pipe through NULL by the left shift operator. As a result, nothing happened. That means this is correct code grammatically.

And I tried out little bit different code as below.

(void)0 << "hi" << endl;

Of course, It didn't work.

Lastly, I tried out this code.

string tmp;
cin >> (1 < 2 ? 0 : tmp);

It was compiled but crashed in runtime. (It works if the sign is changed inversely but the input is not stored in tmp.)

Is there someone who can walk me though what to happen in the first case? (in terms of compiler or low level if possible)

Upvotes: 3

Views: 125

Answers (3)

Keith Thompson
Keith Thompson

Reputation: 263307

1 < 2 ? (void)0 : cout << "hi" << endl;

The other answers have pointed out that the operator precedence gives this a different meaning from what you assumed, so the above is equivalent to:

(1 < 2)
    ? (void)0
    : (cout << "hi" << endl);

But it's still illegal.

If the second or third operand of the ?: conditional operator is of type void, then the other must also be of type void or must be a throw-expression.

Casting the third operand to void would address that:

1 < 2 ? (void)0 : (void)(cout << "hi" << endl);

If you can update your question to show the exact code you're asking about, we can probably explain it better.

It would also be interesting to see the context in which this appears. By itself, it would be much more legible as an if statement.

Upvotes: 1

jamesdlin
jamesdlin

Reputation: 89995

<< has higher precedence than ?:, so:

 1 < 2 ? (void)0 : cout << "hi" << endl;

is actually equivalent to:

(1 < 2) ? (void)0 : (cout << "hi" << endl);

not to:

 ((1 < 2 ? (void)0 : cout)) << "hi" << endl;

(And, of course condition ? then_expression : else_expresion won't evaluate else_expression at all if condition is true.)

Upvotes: 3

OneOfOne
OneOfOne

Reputation: 99254

You're misreading it, 1 < 2 ? (void)0 : cout << "hi" << endl; translates to :

if(1 < 2) {
    (void)0; //do nothing
} else {
    cout << "hi" << endl;
}

condition ? true-state : false-state; is called a ternary operator, it absolutely has nothing to do with <<.

Upvotes: 5

Related Questions