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)

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
5.4 -- Increment/decrement operators, and side effects

137 comments to 5.5 — Comma and conditional operators

  • Benur21

    Hi Alex!
    It would be nice to have some kind quiz at the end of most chapters. It's good that many chapters already have it. But others, like this one, don't, and it's boring to read the chapter, reach the end and just move on to the next one, basically forgetting it. I only read a few entire chapters each time, and with several days in between. So when I come to read the next chapter it's hard to remember what I learnt on last chapters because there is no quiz.
    Note: By chapter I mean, eg: 3.3 is a chapter, 3.4 is another chapter.
    Good work, though, nice tutorials to learn C++ without having to read a book. Just wanted to point this out.

  • Ashie

    Sweet, this just helped shorten the code from the last lesson!

  • Anon

    Hi Alex, I was wandering: String can't be casted into int in the code right at the end, therefore it won't compile. But, int can be casted into string. So, if the roles were flipped, would the code compile than? and if not, why?

    • nascardriver

      Hi Anon!

      > But, int can be casted into string
      Explicitly, yes, but there needs to be an implicit conversion sequence, which there is not.
      We can also cast a const char* to an int explicitly.

      > So, if the roles were flipped, would the code compile than?
      No, the order doesn't matter.

      > and if not, why?

      For this statement to be valid at least one of the three must be satisfied:
      * B and C have the same type.
      * There's an implicit conversion sequence to transform B to C (B can implicitly be cast to C).
      * There's an implicit conversion sequence to transform C to B (C can implicitly be cast to B).

      In this example, none of these cases is true.
      * const char* is not the same type as int.
      * int cannot be implicitly converted to const char*.
      * const char* cannot be implicitly converted to int.

      This is valid, because int and double can implicitly be cast to each other. One direction would've been enough to compile.

      * Lesson 4.4 - Implicit type conversion (coercion)
      * Lesson 4.4a - Explicit type conversion (casting)

  • Chris

    Hi Alex, i was just wondering, in your last snippet of code, you have false set in like this:

    const int classSize = getClassSize(false);

    I was wondering why you have to do that? Shouldn't getClassSize(); return a true or false value, then set the value based off of what the answer to that is?

    • nascardriver

      Hi Chris!

      @getClassSize returns an int and takes a bool as parameter.

      Passing false will set @isBigClassRoom to false and cause @getClassSize to return 20. @classSize is 20.

  • Vu Dang

    Alex, I have a question. What is actually an initializer in your statement: "the initializer can't be a statement."

    • Alex

      The initializer for a variable can't be a statement -- it must be an expression. That expression could be a literal value (e.g. 20 or 30), or a function call, or any other valid expression.

      But that statement sort of missed the mark altogether. I've updated the lesson with a better and more accurate explanation of why an if/else can't be used (directly) in the const variable case.

      Let me know if it makes more sense now.

    • Dear Teacher, please let me answer this question:
      Mr. Vu Dang, our dear Teacher, by "initializer", in the context of this example, means the value of variable "classSize", that is 30 or 20, eventually 20. Regards.
      Regards dear Teacher, and many thanks for permission to answer question.

  • Nick M

    Just wanted to say thanks very much for this resource. Things are explained from first principles here. Most other C++ learning resources (i've used many) seem to introduce concepts in a somewhat haphazard way. This is the most clear, and best learning tool I've found so far.

  • Hema

    Will If statement and conditional operator act the same way in all the cases?

  • James Ray

    Hi Alex,

    You have a few examples that have cout rather than std::cout. For consistency with earlier lessons, should you use std::cout, rather than just cout?

  • Matthieu B.

    There's an empty code section of one line right at the end of this lesson.

  • Grace

    Could you please evaluate this and tell me why 1 is displayed?
    int x=10,y=5;
    cout<<(x>y)&&((x-2<2) || (!y>5));


    • Alex

      Breaking it down:
      std::cout << (x>y)&&((x-2<2) || (!y>5)); becomes
      std::cout << (true)&&((false) || (true)); becomes
      std::cout << true&&true; becomes
      std::cout << true
      which prints as 1, since std::cout prints booleans as integer values by default.

    • David

      std::cout <<(x>y) && ((x-2<2) || (!y>5));

      std::cout << true && (false || true);

      std::cout << 1 && (0 || 1);

      Because the boolean (0 || 1) evaluates to true, we have
      std::cout << 1 && 1;

      Since << has higher precedence than &&, << evaluates first.
      (std::cout << 1) && 1;

      So "1" ("true") is printed in the console, and the rest is discarded.

      If we had this instead
      std::cout << (1 && 1);

      "1" ("true") would still be printed because the boolean (1 && 1) evaluates to true.

  • subh

    I used code::blocks IDE and executed below statements. Outcome is 0;  Contrary to the given statement about comma operator (,).

    int x = 0;
    int y = 2;
    int z = (++x, ++y)

  • Nyap

    so basically;
    1) sizeof operators will also evaluate to the size of a variable if you give it's name/identifier
    2) comma operators are a way of combining multiple expressions. They evaluate to the value that is on the very right
    3) conditional operators:
           (expression) ? (value to evaluate to if expression is non-zero/true) : (value to evaluate to if expression is zero/false)

  • Peng

    Consider the above example, the GCC complain:
    F:\LearnCpp\main.cpp|12|error: 'classSize' was not declared in this scope|
    "It’s worth noting that the conditional operator evaluates as an expression, whereas if/else evaluates as statements. ", what's the exact meaning of this? Could you give the more detailed about it?
    Nothing could be better for your help, Thanks Alex :)

    • Alex

      The problem here is that the lines that execute as part of the if/else statement are considered to have block scope, so the above actually compiles as if you'd typed:

      In this context, it's a little easier to see that classSize is local to the block, and thus not accessible to be printed using std::cout.

      Remember: an expression is a sequence of operators and operands that evaluates to a value. A statement is the C++ equivalent of a sentence, and ends in a semicolon. You can define a named variable in a statement, but not an expression.

  • Karl

    how to replace if else with conditional operator here??

  • Domenic D

    I believe you said that the parts after the condition must be expressions not statements. Kinda wondering if there is a reason for that.


    After the condition the two parts above are statements. Right? This works in CB but why should I not do this. Confused???

    • Alex

      cout << "whatever" is actually an expression, not a statement (remember, statements end in a semicolon).

      Note that you can make any expression into a statement by putting a semicolon on the end of it (these are called expression statements). So when we write cout << "whatever"; this is an expression statement.

      As for the reason why statements are disallowed inside the conditional operator, the conditional operator itself is an expression, sso what is inside it must also be an expression so the whole thing can evaluate to a single value. Otherwise you could do some weird stuff like this:

      What does this even mean?

  • Jim

    You've used z = ( x, y ) as a comma separator.  Does the compiler first assign z = x , then assign z = y, so this is the reason the comma uses the right most operand?

    Is it true that if the code were z = ( u,v,w,x,y ) that  all of these variables would be assigned one at a time to z and end up with z = y?  Is it also possible to use integers
    z= ( 1, 2 )?

    • Alex

      No, (x,y) is evaluated first to produce the value y, and then y is assigned to z. At no point will x be assigned to z.

      For z = (1, 2), (1, 2) should evaluate to 2, and then the value 2 will be assigned to z.

  • bram jorna

    what is the usefull use of the conditional operator?
    i get that it makes the code smaller. but doing so it might confuse you and give errors.
    does it have any other advantages over a normal if/else statement apart from reducing the size of the typed code??

    • Alex

      Yes. The conditional operator evaluates as an expression, whereas if/else evaluates as a set of statements. This means the conditional operator can be used in places where if/else can not.

      For example, when initializing a const variable:

      There's no equivalent if/else statement for this, since const variables must be initialized when defined, and the initializer can't be a statement.

      • Chris

        I don't understand your sentence "There’s no equivalent if/else statement for this, since const variables must be initialized when defined, and the initializer can’t be a statement.". what is the point?

        I can use if/else statement like this and work well :

        • Alex

          I think we're quibbling about the meaning of "equivalent". You're using it in the sense of "produces the same result", I'm using in the sense of "as good as".

          While your suggestion does work (in this case), it has some serious downsides:
          * It's a lot more complicated (7 lines instead of 2, and introduces a new variable into the scope)
          * It's may be a lot slower, because you're doing an assignment and an initialization, whereas the conditional version does only the initialization. Integers are cheap to copy, so in this case it's probably not a big deal. But if this were a large array, you wouldn't want to take the performance hit of making an extra copy.

          Therefore, I think it's safe to say it's not as good as using a conditional.

          I'll change the word "equivalent" to "satisfactory" to indicate the statement is a comprehensive judgment, not just based on whether it works.

  • Pravasi Meet

    Consider following program (See live demo &

    The above program prints 4 as an output in C but prints 20(sizeof array) as an output in C++. The comma operator in C always results in an r-value even if its right operand is an l-value, while in C++ the comma operator will result in an l-value if its right operand is an l-value. This means that certain expressions are valid in C++ but not in C. That's why in above C program there is lvalue to rvalue conversion occurs but in C++ it always results in locator value.
    Following is simple example to demonstrate it.

    When you compile above program in C the C compiler will give following error:
    [Error] lvalue required as left operand of assignment

    It would be better If you add this information.

  • afshin javani

    is it possible ,to make a program with c++ for android devices ?

    int my knowledge=little,why=many;

    while((my knowledge==little)||(why==many))
       If(your answer==yes)

       my knowledge++;

    • Devashish

      Yes, it's possible. You can use the NDK plugin with eclipse for writing in C++. But, because C++ is not the primary language used to write for android, I think you should learn java. If you are familiar with C++, it won't take more than a month to write codes in java. It's a truth that Java is the favorite language chosen by thousands of programmers, to write apps for android.

  • Aryan

    How do you avoid using a comma operator? I mean a comma is a comma. And the syntax of comma operator and normal comma is astoundingly similar!
    Also how does the compiler know that I am using a comma operator and not a comma or using a comma and not a comma operator? (Sorry for so many commas)  ;)

    • Alex

      I'm not sure what you mean. The C++ compiler is smart enough to infer when you're trying to use the comma operator and when you're not.

      Typically in C++ the comma operator is used with for loops and that's about it. The other uses of comma are just to fulfill the expected syntax (e.g. to separate function arguments or parameters) -- they're not a use of the comma operator.

  • Aryan

    How does the compiler know that I am using the normal comma and not the comma operator? Is it that the comma operator gets activated or something when its around some particular type of syntax like the loop that you mentioned.
    Also if I want to use comma operator how does the compiler know that I am using the operator and not the normal comma?
    (I hope I didn't gave you a headache with so many commas) ;)

    • Alex

      When the compiler compiles your program, it breaks down each line into components and checks them against its list of valid syntax to ensure each line is valid.

      In some of those rules, the comma symbol is used as a separator (e.g. to separate multiple arguments or function parameters).
      In other rules, the comma is allowed as an operator (e.g. in an expression).

      The language has been defined in such a way that there is no ambiguity about which use is intended (otherwise, the compiler wouldn't be able to compile your program without additional input from you).

  • Mr D

    ok, so:

    means that the compiler only asks “is x bigger then y” (if so, output 1, otherwise 0) and the

    part is just ignored?

    (By the way, just so you know, when one posts a comment, then later edits it, after the edit the post no longer formats correctly using


    • Alex

      Yes, I believe your analysis is correct.

      I noticed that the code formatter, the AJAX comment editor, and the "literal comments" plugin (that ensures code outside of code tags doesn't get treated as HTML) don't play together correctly. It's something we'll have to live with for now.

  • mike

    Why should we avoid calling it the ternary operator?

    • Alex

      Because that's not its name. It's the conditional operator. :)

      Also, there aren't any guarantees there won't ever be another ternary operator.

  • techsavvy....aye

    how would you use the above snippets for programming ? can you give an example ?

    • Darren

      Finding the minimum or maximum between two values e.g.

      Templating is an advanced topic but essentially means you can call this function with any type you like, so long as the type has the greater-than (>) and less-than (<) operators defined.

  • Catreece

    The arithmetic if is handy to know it exists, but I don't think I'll ever use it myself. It's far more concise, but also far less clear what's going on and it took a few re-reads of the example code to figure out what was being said even after understanding how it works because of the odd syntax.

    I figure it'll be handy when reading over the code from other people, but I'm a stickler for keeping things as easy to read and understand as possible since my past experience has been that, in a week, you won't remember why you did something a certain way and if you have to change it, you'll definitely save time by it being easier to read than you would've saved by typing out a few more lines.

    I suppose if you used the arithmetic if constantly, all the time, you'd get used to the format eventually, but even then it's still a matter of consistency: if you're going to do ten of the same kind of action, do it the same way each time so that you don't have to mentally juggle where the variables go when trying to adjust something, especially if you have to adjust all ten of those functions in a similar manner that's just barely off enough that you can't just do a global fix. At that point it's nice to have all ten of those functions looking nearly identical so that it's blatantly obvious what needs to be changed where without having to think about what needs to be altered.

    I guess that's just my personal preference, but I'd always favour easier to read code over faster to write code if given the choice. =P

  • bacia

    return x, y;

    would this only return y?

  • bla

    It's a bit confusing that a lower precedence corresponds to a higher precedence level here. Is that the standard way of saying it?

  • jeremy

    Is it bad form to place the assignment inside the arithmetric if? eg.:

    It compiles fine with Codeblocks and GCC.
    This seems more elegant IMHO.

    • Alex

      I think

      is the preferred form for several reasons.

      1) It's not as redundant (there's only one assignment to z instead of two).
      2) It makes it clearer that something is being assigned to z.

  • manju23reddy

    using sizeof function
    will resolve during
    1. runtime
    2. compile time 3. pre-compile time

    plz answer me

  • Steve

    Hey, whats the point of the comma operator if all it does is evaluate to the rightmost operand?

    • The only place I see the comma operator commonly used is inside loops, to increment multiple variables, especially for loops. We cover for loops in more detail in Chapter 5.7 -- For statements.

      Using the comma operator is a useful way to increment or decrement multiple variables in a single expression. For example:

      Due to the particular syntax constraints on for loops, all your variables have to be modified in a single expression -- this allows you to do that.

Leave a Comment

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