Search

5.5 — Comma and conditional operators

The comma operator

Operator Symbol Form Operation
Comma , x, y Evaluate x then y, returns value of y

The comma operator (,) allows you to evaluate multiple expressions wherever a single expression is allowed. The comma operator evaluates the left operand, then the right operand, and then returns the result of the right operand.

For example:

First the left operand of the comma operator is evaluated, which increments x from 1 to 2. Next, the right operand is evaluated, which increments y from 2 to 3. The comma operator returns the result of the right operand (3), which is subsequently printed to the console.

Note that comma has the lowest precedence of all the operators, even lower than assignment. Because of this, the following two lines of code do different things:

This makes the comma operator somewhat dangerous to use.

In almost every case, a statement written using the comma operator would be better written as separate statements. For example, the above code could be written as:

Most programmers do not use the comma operator at all, with the single exception of inside for loops, where its use is fairly common. We discuss for loops in future lesson 5.7 -- For statements (Not in this chapter 5, but L.5. Please excuse the disjoint lesson numbering.).

Best practice

Avoid using the comma operator, except within for loops.

Comma as a separator

In C++, the comma symbol is often used as a separator, and these uses do not invoke the comma operator. Some examples of separator commas:

There is no need to avoid separator commas (except when declaring multiple variables, which you should not do).

The conditional operator

Operator Symbol Form Operation
Conditional ?: c ? x : y If c is nonzero (true) then evaluate x, otherwise evaluate y

The conditional operator (?:) (also sometimes called the “arithmetic if” operator) is a ternary operator (it takes 3 operands). Because it has historically been C++’s only ternary operator, it’s also sometimes referred to as “the ternary operator”.

The ?: operator provides a shorthand method for doing a particular type of if/else statement. Please review lesson 4.10 -- Introduction to if statements if you need a brush up on if/else before proceeding.

An if/else statement takes the following form:

if (condition)
    statement1;
else
    statement2;

If condition evaluates to true, then statement1 is executed, otherwise statement2 is executed.

The ?: operator takes the following form:

(condition) ? expression1 : expression2;

If condition evaluates to true, then expression1 is executed, otherwise expression2 is executed. Note that expression2 is not optional.

Consider an if/else statement that looks like this:

can be rewritten as:

In such uses, the conditional operator can help compact code without losing readability.

Parenthesization of the conditional operator

It is common convention to put the conditional part of the operation inside of parenthesis, both to make it easier to read, and also to make sure the precedence is correct. The other operands evaluate as if they were parenthesized, so explicit parenthesization is not required for those.

Note that the ?: operator has a very low precedence. If doing anything other than assigning the result to a variable, the whole ?: operator also needs to be wrapped in parenthesis.

For example, to print the larger of values x and y to the screen, we could do this:

Or we could use the conditional operator to do this:

Let’s examine what happens if we don’t parenthesize the whole conditional operator in the above case.

Because the << operator has higher precedence than the ?: operator, the statement:

would evaluate as:

That would print 1 (true) if x > y, or 0 (false) otherwise!

Best practice

Always parenthesize the conditional part of the conditional operator, and consider parenthesizing the whole thing as well.

The conditional operator evaluates as an expression

Because the conditional operator operands are expressions rather than statements, the conditional operator can be used in some places where if/else can not.

For example, when initializing a const variable:

There’s no satisfactory if/else statement for this. You might think to try something like this:

However, this won’t compile, and you’ll get an error message that classSize isn’t defined. Much like how variables defined inside functions die at the end of the function, variables defined inside an if or else statement die at the end of the if or else statement. Thus, classSize has already been destroyed by the time we try to print it.

If you want to use an if/else, you’d have to do something like this:

This one works because we’re not defining variables inside the if or else, we’re just returning a value back to the caller, which can then be used as the initializer.

That’s a lot of extra work!

The type of the expressions must match or be convertible

To properly comply with C++’s type checking, both expressions in a conditional statement must either match, or the second expression must be convertible to the type of the first expression.

So while you might expect to be able to do something like this:

The above example won’t compile. One of the expressions is an integer, and the other is a string literal. The compiler will try to find a way to convert the string literal to an integer, but since it doesn’t know how, it will give an error. In such cases, you’ll have to use an if/else.

So when should you use the conditional operator?

The conditional operator gives us a convenient way to compact some if/else statements. It’s most useful when we need a conditional initializer (or assignment) for a variable, or to pass a conditional value to a function.

It should not be used for complex if/else statements, as it quickly becomes both unreadable and error prone.

Best practice

Only use the conditional operator for simple conditionals where you use the result and where it enhances readability.


5.6 -- Relational operators and floating point comparisons
Index
5.4 -- Increment/decrement operators, and side effects

140 comments to 5.5 — Comma and conditional operators

  • pop

    Hi Alex, In the "Comma as a Separator" section, it is advised as

    But as I have been learnt C for initializing two integer variables as:

    Why this is wrong?.

    • nascardriver

      It's legal in C++ too, but discouraged. It's harder to read than 1 initialization per line and allows mixed types in the same line when using pointers.

  • Soulhydra

    My question is "why you had used const keyword in the below program"??

    Can't we write the above code in this way..

  • alsaht

    thanks for the great tutorials

    i have two questions :
    1-is the seperator comma an operator?
    2- is every sybmol in c++ an operator ?

  • A typo:

    > Note that comma has the lowest precedence of all the operators, even higher than assignment.

    should read `lower than assignment` instead of `higher` i.e.

    Note that comma has the lowest precedence of all the operators, even lower than assignment.

    (thanks for this site)

  • kutlu

    I wrote a code that a dc motor opened and closed by rs232 communication. But I want to see the initial condition of that motor( motor open and close a cover) . There are  limit switches on both side of cover. When it close or open fully, the cover touch the related limit switch. Limit switch signal pin go through ground when it is pushed. I want to see the current position of the cover when I open the system. Does the initialization for that system seem true? I use conditional operator as you advise

    • nascardriver

      `BUTTON_INC_LIMIT` looks like a macro (because it's all caps). If this really is the name of a variable, your code is correct.

      • kutlu

        Thank you for your answer. Yes it is a macro ( it defines digital pin of microcontroller), I wrote it before I read your tutorial. When I revise the code, I will turn macro to "constexpr int".

        • nascardriver

          Then the code won't work, or I misunderstood what you want to do. `backCoverStatus` will always have the same value, because its the index of the pin, not the pin's value. You need to read the value of the pin and use that in your conditional statement instead.

          • kutlu

            Yes, you are right, I have missed that point. I fixed it.

  • Yousuf

    "Conditional Operator" is beautiful and handy. Now I understand why C++ is being called Swiss Army Knife.

    I am using GCC 10.2.0. And I always use this "-std=c++20 -Wall -pedantic -Wsign-conversion -Wconversion  -Werror" compiler flag. So fortunately GCC warns me and stop compilation as a result when I am trying to use comma operator like this way:

    or

    .

  • Chayim

    What’s the definition of the difference between expression and statements? So that if/else dies after else but conditional operation does not die after its expression. Why does a statement die after the statement but an expression does not die after the expression. Is the definition that a statement is a function but an expression is not? int is also a function so why does int not die after it’s defined but if/else statement does?

    Already got the answer... you won’t answer...

  • BeanSprugget

    At the beginning of the article, "For example, the above code could be written as:" should be changed to "For example, the first example could be written as:",
    because the code above that paragraph is not the correct one being mentioned.

  • Chayim

    What’s wrong with this code? -larger- does not need to be entirely in parentheses in this case

  • sami

    I was wondering why the result is " 0 15 "? While " 0 20" was expected!

    • nascardriver

      You're doing this

      `std::cout <<` is (almost) always `true`. As a side note: Initialize variables with list-initialization.

  • sami

    "z = a, b; // evaluates as "(z = a), b", so z gets assigned the value of a, and b is evaluated and discarded."

    Because assignment operator (=) has right to left associativity, shouldn't "b" first gets evaluated and then assigned to "z"?
    When we say L->R , we mean starting from far-left of an expressions, how about R->L, is n't far-right, which is 'b' in this example above?

    • nascardriver

      The comma operator has the highest precedence of all operators, it always happens last.
      This is the code after making the precedence explicit

      No associativity comes to play here. Associativity only matter when you have more than 1 of an operator in sequence, for example

      Here, associativity would cause the order being like this

      The order of evaluation of individual components (z, a, b) is a different story. It's unrelated to precedence and associativity. There is currently no dedicated lesson about the order of evaluation and it's too much to write in a comment. In important cases, we note it in the lessons.

      • sami

        Thank you so much nascardriver for all of responses. I learned a lot and still learning a  lot. Thank you sooooo much.

      • 3li Mot 3alim

        you mean "the lowest precedence"..

        • nascardriver

          I mean "the highest precedence". I always mix them up too. The lower the precedence, the earlier it is applied. The comma operator has the highest precedence, meaning it is applied last.

          • 3li Mot 3alim

            could you check the third paragaph from top.
            "Note that comma has the lowest precedence of all operators, even lower than assignment."
            Also, @nascardriver  as precedence means ( the condition of being dealt with before),
            don't you think the high precednce should mean the earlier to apply?

  • sami

    When we are passing a function some arguments, then doesn't that commas inside the parentheses consider as "comma operator"?if not, how should we distinguish this?

    Like :

    • nascardriver

      That's not a comma operator. If you want to use a comma operator in a function call, wrap it in another pair of parentheses.

  • SZS

    Hello, thanks for the tutorials, they are carrying my quarantine.

    I think you missed this lesson when you renamed/reordered them, as for statements are listed as 5,7 so it seems it's two lessons apart, when in fact it's waaaay further than that.

    • nascardriver

      We have 2 chapter 5, that's confusing. I added a note to this lesson to prevent disappointed when for loops aren't as close as advertised.

  • JackTheHopper

    Thanks for informative and helpful community.

    I am trying to develop a code using the condition operator, could someone please explain why this method is not working?

    but this works

    I understand this may not be a good practice for coding.

    • nascardriver

      this is not be a good practice for coding.
      The conditional operator is there to get the value of one of two expressions. A `return`-statement is not a value. An assignment is a value (at least in your example).
      What you want to do is return unconditionally, but make the return value dependent on your modulus.

      Although this works, it's nonsense. The comparison already produces a boolean, you can return it immediately.

  • J

    I'm just tooling around with the conditional operator and wondered if you can have it execute functions. For some reason when trying to execute this code, the darn thing won't even compile. I've tried separating this code using if/else statements instead and that didn't work either. The compiler (VS) isn't showing any errors but it absolutely refuses to execute.

    Could anyone provide insight? Are you not able to call functions this way? Thanks in advance for the help.

    • Alex

      Works fine for me both in Visual Studio 2019 and using online compilers (e.g. http://cpp.sh/)

      • J

        I'm not really sure what the issue would be, then... I'll just see about getting another compiler maybe? Didn't really think about trying the code on another compiler before asking, sorry. Thank you for the reply.

        • Alex

          Are all programs failing for you, or just this particular one?

          • J

            Sorry for the late reply!

            Yes, just this particular one. There aren't any other programs that have this problem. When I tweak the cpp to do something else it runs just fine.

            • Alex

              I'm mystified. Maybe you're running into some obscure compiler bug? Alternatively, maybe some external piece of software (e.g. anti-virus or anti-malware) is blocking the execution of that particular program and not others?

              • J

                You were spot on with the anti-virus. Turns out I just needed to add an exception for VS to let the program run, and I won't bother asking why it'd let some programs run but not others... Silly thing was labeling it malware. Thanks for helping me out with this!

  • Michael

    I'm confused as to why you are claiming that the spaceship operator is a ternary operator. cppreference seems to show usage of this operator as follows: `x <=> y` (x and y are the only 2 operators).

    Here's the link: https://en.cppreference.com/w/cpp/language/operator_comparison#Three-way_comparison

    It returns something >0, <0, or ==0. So the "three-way" seems to refer to the output (i.e. it's "one more" than two-way Boolean output).

    So even in C++20, there's still only one ternary operator. Is this right?

  • Tom Bauer

    Would this be a reliable workaround to the last problem?

    • nascardriver

      Yes, but that's not a recommended way of using the conditional operator. Only use the conditional operator if you use it's result. Use an if-statement otherwise.

  • Jake

    In the last example:
    std::cout << (x != 5 ? x : "x is 5"); // won't compile
    You go on to explain that:
      One of the expressions is an integer, and the other is a string literal.

    How is the 5 a string literal?  It looks like a perfectly legitimate integer literal to my eyes.

    What am I missing?

    • nascardriver

      The two possible results must be the same or one must be convertible to the other.

  • Matt

    Wow, more info regarding the language that my Intro course 'conveniently' left out. I am beginning to see just how much in terms of concepts, tools, and best practices were completely omitted from the assigned C++ textbook. Unlearning the bad habits the book taught is going to take some work.

    (If your curious, the textbook I was assigned was "C++ Programming: From Problem Analysis to Program Design" by D.S. Malik, and the very first thing it does it teaches its students use namespace std instead scope reducing with std::, and the professor never offered any feedback for improving code in any way.)

    • Yep, a lot of teaching resources teach `using namespace std;`, because it's convenient and makes to code smaller. But even if they say that it's bad, when they use it, their students will too.

      • Ikenna

        I have a question if you don't mind me asking. Has a lot changed in the C++ language architecture to start to worry about not reading books on C++ that has been dated since 2010 ?

        • nascardriver

          Yes, a lot has changed since 2010. You can read the book if it's about a specific topic, eg. algorithms, networking, etc., but I can't recommend reading it to learn the language.
          If you're planning on using an old standard (For embedded system with an old compiler for example), you can also read the book. However, it's easier to learn the current language version and stop using new features than it is to learn an old language version and read up on everything you missed.

  • Benur21

    I think it's worth noting that the else part on these ?: statements is not optional like in the if's, because it always must return something. Sometimes we could use empty string "" if we want it to return nothing. For example, in the following code I found at lesson 5.5:

    I was thinking if I could do like this:

    but obviously it needs an else return.

  • Randle

    I remember learning the conditional operator in uni, but was never shown a proper example where it was necessary, so I ignored it. Thank you for providing a clear example of its usage!

  • Brandon

    How could I use the conditional operator in place of an if/else with multiple statements? I'm practicing by converting if/else statements to use the conditional operator but what about those with multiple else if's like a switch statement? Is that possible? or would it be bad practice since the point is to reduce the clutter of code? Thanks.

    EDIT: I just noticed " It’s worth noting that the conditional operator evaluates as an expression, whereas if/else evaluates as a set of statements."

    But still, can I only evaluate a single expression at once right?  Sorry if this sounds weird.

    • Hi Brandon!

      The conditional operator should only be used when you need the result of the expression.

      You could use the comma operator to get what you want

      But don't do it, it's ugly, use if-statements.

  • Jules

    So i wrote a simple assembly program to find the square of a number (2 in this case, haven't given the functionality of user input):
    #include "pch.h"
    #include <iostream>
    int power(int);
    int main()
    {
        std::cout << "Hello World!\n";
        std::cout<<power(2);
    }

    int power(int x)
    {
        _asm
        {
            mov eax,x
            imul eax,x
            mov x,eax

        }
        return x;
        
    }

    my question is :
    in the instruction mov x,eax does the compiler already know that the contents of eax should be moved into the MEMORY LOCATION of "x"
    because the contents of the eax register cannot be moved into a variable.

    consequently mov [x],eax works as well.
    just wanted to know if the c++ compiler is optimized in handling asm in a way that traditional assemblers like NASM or FASM aren't.

  • Jeremy

    I can understand the logic of variables inside of functions being destroyed after the function call is over, but is there a specific reason why if/else statements share the same scope?

    • Alex

      The C++ specification says that if the if-statement or else-statement are not written as compound statements, they should be treated as if they were. So:

      Is treated as if it were written:

      And although we haven't covered blocks/compound statements yet (that happens in chapter 4), they behave similarly to functions in that local variables defined inside a block die at the end of the block.

  • aleksandr.a

    So you can use the conditional operator?
    Thank.

  • Rai

    I tried using the conditional operator with one of the older lesson project.

    How would you use conditional operators for the if statement here? I tried doing it with this :

    But I was getting an error saying "error C4716: 'getInteger': must return a value"

    • Without the full @getInterger function I can't tell you what your problem is.
      Here's how you could do it

    • leonidus007

      Maybe this can help..

      #include <iostream>
      int getInteger()
      {
          std::cout << "Enter a single digit integer: " << std::endl;
          int input;
          std::cin >> input;
          return input > 0 ? (input < 10 ? input : -1) : -1;
      }
      int main()
      {
          int y{ getInteger() };
          std::cout << y;
          return 0;
      }

Leave a Comment

Put all code inside code tags: [code]your code here[/code]