C++ Ternary operator question

Started by
8 comments, last by Poita 16 years, 3 months ago
Hi guys, Something has just been bugging me today with regards to part of an implementation of Merge Sort, whereby the merging loop uses the ternary operator. I suddenly had the thought that my code might actually be undefined behaviour. I initially thought it was fine, but now I'm not sure. The line of code in question is:
        sortArr[c++] = (rightArr < leftArr[a]) ? rightArr[b++] : leftArr[a++];
The assumption this code makes is that only either rightArr[b++] OR leftArr[a++] is executed. Now, all is fine and dandy when the second and third expressions used in the ternary operator don't have side effects. E.g.
int foo = (bar == 42) ? 10 : 20;
But can someone check the standard and see if it is possible that in the first example I gave that both a and b might be incremented? It is working as desired in VS2005 Express, but I'm worried that even though only the result of one of those expressions will be assigned to sortArr[c++], that it might actually evaluate both anyway, on a different compiler and increment a and b. I guess a simpler example that hilights the issue would be:
int foo = (bar == 42) ? a++ : b++;
The reason I'm particularly unsure whether it will execute only one of the side effects is that when using the ternary operator in template meta-programming in the past I've seen evidence that it evaluates both sides. I've done a bit of a search on the net, but couldn't find anything that goes into enough detail to answer my question. Perhaps I just need some reasusrance.
"In order to understand recursion, you must first understand recursion."
My website dedicated to sorting algorithms
Advertisement
I don't know what the standard says, or if other compilers will handle it differently. One option is just to code it so this won't happen. Just use a regular if-statement and forget about the ternary operator.
it should evaluate just like the if statement.
5.16 §1 says: ... "Only one of the second and third expressions is evaluated."

To make it is hell. To fail is divine.

I have a rule when I code:

No matter how defined a particular code snippet's behavior may be in the spec, if I can't immediately sort out what is going on, the code is bad and should be rewritten more clearly.

In the case of the ?: operator, it's the equivalent of an if/else block (that is, "only one of the second and third expressions is evaluated." [quoted from the C++ standard]).

However, someone (such as yourself) may not find the meaning of such code instantly clear, and thus it might not be a bad idea to use an if/else block for clarity.
Quote:Original post by Zao
5.16 §1 says: ... "Only one of the second and third expressions is evaluated."
Thanks very much, that's exactly what I was after.

I may very well commonly write such things out as an if-statement in future when side-effects are concerned, but it is good to know that the original code was okay. [smile]
"In order to understand recursion, you must first understand recursion."
My website dedicated to sorting algorithms
No matter what the standard says, you shouldn't write ambiguous code like that unless it is absolutely 100% necessary. If you have to think about what it does then you should rewrite it to be more obvious.
-----------------------http://poita.org - C++ and D programming articles.
Quote:Original post by Poita
No matter what the standard says, you shouldn't write ambiguous code like that unless it is absolutely 100% necessary. If you have to think about what it does then you should rewrite it to be more obvious.

Are you the same Poita from the Supreme Commander official forums? I knew I recognised that name from somewhere.
NextWar: The Quest for Earth available now for Windows Phone 7.
Quote:Original post by Poita
No matter what the standard says, you shouldn't write ambiguous code like that unless it is absolutely 100% necessary. If you have to think about what it does then you should rewrite it to be more obvious.
The whole point is that I didn't ever have to think about what it did. Until today I knew exactly what it did, or so I thought. I had no reason to even question it until today. Hence I had no reason to ever think it needed to be rewritten.[smile]

How is it going to be any different for the next person, and when is any way of writing code ever absolutely 100% necessary?
"In order to understand recursion, you must first understand recursion."
My website dedicated to sorting algorithms
Quote:Original post by Sc4Freak
Quote:Original post by Poita
No matter what the standard says, you shouldn't write ambiguous code like that unless it is absolutely 100% necessary. If you have to think about what it does then you should rewrite it to be more obvious.

Are you the same Poita from the Supreme Commander official forums? I knew I recognised that name from somewhere.


lol, yes that's me.

Quote:The whole point is that I didn't ever have to think about what it did. Until today I knew exactly what it did, or so I thought. I had no reason to even question it until today. Hence I had no reason to ever think it needed to be rewritten.

How is it going to be any different for the next person, and when is any way of writing code ever absolutely 100% necessary?


Well, most C++ books/tutorials warn you about using expressions like (a++ || b++) and using the ++ or -- operators in macros, so I would hope that these should send alarm bells ringing when used. If not, then I guess that's just something that needs to be learned, but once you do, you should avoid code like that, even if you know it will work as you want.

I can't think of any examples of code that is 100% necessary. Regardless, my point was to avoid ambiguous code.
-----------------------http://poita.org - C++ and D programming articles.

This topic is closed to new replies.

Advertisement