Search

1.9 — Introduction to expressions

Expressions

Consider the following series of statements:

Each of these statements defines a new variable and initializes it with a value. Note that the initializers shown above make use of a variety of different constructs: literals, variables, and operators. Somehow, C++ is converting each of these literals, variables, and operators into a single value that can be used as the initialization value for the variable.

What do all of these have in common? They make use of an expression.

An expression is a combination of literals, variables, operators, and explicit function calls (not shown above) that produce a single output value. When an expression is executed, each of the terms in the expression is evaluated until a single value remains (this process is called evaluation). That single value is the result of the expression.

Here are some examples of different kinds of expressions, with comments indicating how they evaluate:

As you can see, literals evaluate to their own values. Variables evaluate to the value of the variable. We haven’t covered function calls yet, but in the context of an expression, function calls evaluate whatever value the function returns. And operators let us combine multiple values together to produce a new value.

Note that expressions do not end in a semicolon, and cannot be compiled by themselves. For example, if you were to try compiling the expression x = 5, your compiler would complain (probably about a missing semicolon). Rather, expressions are always evaluated as part of statements.

For example, take this statement:

If you were to break this statement down into its syntax, it would look like this:

Type could be any valid type (we chose int). Identifier could be any valid name (we chose x). And expression could be any valid expression (we chose 2 + 3, which uses 2 literals and an operator).

Key insight

Wherever you can use a single value in C++, you can use an expression instead, and the compiler will resolve the expression down to a single value.

Expression statements

Certain expressions (like x = 5) are useful by themselves. However, we mentioned above that expressions must be part of a statement, so how can we use these expressions by themselves?

Fortunately, we can convert any expression into an equivalent statement (called an expression statement). An expression statement is a statement that consists of an expression followed by a semicolon. When the statement is executed, the expression will be evaluated (and the result of the expression will be discarded).

Thus, we can take any expression (such as x = 5), and turn it into an expression statement (such as x = 5;) that will compile.

Note that we can make expression statements that compile but are meaningless/useless (e.g. 2 * 3;). This expression evaluates to 6, and then the value 6 is discarded.

Rule

Values calculated in an expression are discarded at the end of the expression.

Quiz time

Question #1


What is the difference between a statement and an expression?

Show Solution

Question #2


Indicate whether each of the following lines are statements that do not contain expressions, statements that contain expressions, or are expression statements.

a)

Show Solution

b)

Show Solution

c)

Show Solution

d) Extra credit:

Show Solution

Question #3


Determine what values the following program outputs. Do not compile this program. Just work through it line by line in your head.

Show Solution


1.10 -- Developing your first program
Index
1.8 -- Introduction to literals and operators

88 comments to 1.9 — Introduction to expressions

  • alfonso

    Would be nice some "deep" look into that "discarded".

    "When the statement is executed, the expression will be evaluated (and the result of the expression will be discarded)."

    Do the result of a + b have a place in RAM, and that place is then available? Or maybe the result resides only in CPU, or ...

    Also

    I know that the program (.exe) resides in memory so 1 and 2 must be there too. But the result, aka 3 is it in memory for a short period of time?

    Sorry I cannot be more precise, my mind is a little fuzzy on this subject :)

    • Both questions are up to the compiler, there is no standard answer. Here's what's commonly done.

      1)
      Assuming @a and @b are run-time values. If their values aren't on the CPU yet, they will be transferred there. The addition is performed and the result is passed to @std::cout::operator<<. Depending on how large @a, @b and the result of the addition are, and which calling convention your compiler is using, the result may stack on the CPU or is pushed onto the stack (RAM). If the value was pushed onto the stack, it will be popped once @std::cout.operator<< finishes. Note that the stack is not mixed with your other values in RAM. It has it's own reserved space.

      2)
      1 and 2 are not in memory. The expression was evaluated at compile-time, so a 3 is stored together with the bytes that make up your code, ie. it's not mixed with other values, because code gets its own space in RAM. Depending on the calling convention, 3 is either pushed onto the stack or it stays on the CPU.

  • Chirayu

    dude at the end it is written that "we can convert any expression into an equivalent statement" instead it should be "we can convert any expression into an expression statement". Or am I wrong??

  • EH

    Hello!
    First of all, thanks for this great & free tutorial!
    I just wanted to add that the answer of question 1 says “A statement are used “.  Although this is obviosly just a typo, it is a bit irritating to read- I would replace it with “Statements are used...”

  • NEERAJ SINGH

    WHAT IS OPERATOR ^

  • Rostyslav

    Good day. Finally I found a good material to start learning C++ for beginners. Before I tried Stroustrup B. - Programming Principles and Practice Using C++, 2nd Edition - 2014 for 1 month. The explanations on this site are quite easy to understand for a newbie, than Stroustrup's. Especially examples which are given here work well, compare to Stroustrup's ones where sometimes you have to guess what to do extra, to make them work.
    Thank you very much for your work!

  • Theodor

    You are the best feel good about your self

  • Welidien

    Hey Alex,

    First of all, this website is amazing!

    I noticed that there is an operator for addition, subtraction, multiplication, division, and an operator for finding the remainder. However, I did not see an operator for finding the exponent. For example, I could not find a specific operator that does something like this:

    2^3 = 8

    I did a quick google search and was unable to find such an operator for C++. Referring to this website: https://www.geeksforgeeks.org/operators-c-c/ the '^' means "Bitwise exclusive OR" (I have no idea what that means.) If you have covered this topic in future lessons, please point me to that page.

    Thank you. :)

  • Hello Sir,

    This is Simon from Bangalore. Actually i am searching job in Cyber Security and i want to learn C++ for career because i am new to real world experience so that asking this question.

    is our website knowledge enough for my field otherwise i want to learn more by books or blogs or any videos ?

    • Alex

      This site will teach you the basics of C++. That will give you the knowledge to learn more about other related subjects. It's definitely not enough to get you a job in cyber security, but it's a good first step along that path.

  • Arush

    Hey Alex,

    Just wanted to tell you that lesson 1.6 seems to not exist. Either that or it's giving me a 404 error. Is there an alternate way to get to it?

    Thank you.

  • My dear c++ Teacher,
    Please add std::endl at the end of lines 6 and 7. I mean that

    With regards and friendship.

  • Tanya

    {    int a,b;
        float x;
        std::cin>>a>>b;
        x=a/b;
        std::cout<<x;
            return 0;   }

    I put the value of a = 10 and b=8, and the answer is given as 1. Why?

  • Andrew

    Alex, you are the man!!

    Quick question - in the code snippet in this lesson, would it be prudent to put "return 0;" before "}" just to be consistent with your style in previous lessons?

    Just a thought - don't know if it has any merit.

    Best,
    Andrew

  • manuel okeke

  • My dear c++ Teacher,
    Please let me comment that at the end of 6th line, "std::endl" should be added, as follows:

    With regards and friendship.

  • Matt

    Possible typo under "Operators":

    "Note: One of the most common mistakes the new programmers make is to confuse the assignment operator (=) with the equality operator (==)."

    I think maybe you meant to write "that new programmers" instead of "the new programmers".

  • Alfred O.

    Hey Alex, I'm curious about a few things I'm wondering you could tell me about, concerning expressions. The question itself isn't too bad, it's just difficult to word clearly and brief. After some research, I had come to this conclusion:

    When an expression evaluates, a temporary object (often called a "temporary") is created to hold the result. This object exists until the end of the full expression, and then it is discarded. If nothing is done with the result of an expression (i.e., the expression has no side effect) it is generally considered a waste.

    ^ Not entirely sure if this is true. This is how I envision an expression evaluating:

    int x = 0, y = 10, z = 15;
    x = y + z;

    1. x, y, and z "evaluate" but the order of such is not specified. A temporary object is created to hold each of their values.
    2. y (10) and z (15) evaluate to 25, another temporary object is created to hold this value.
    3. 25 is copied into x.
    4. All temporaries are destroyed, in the reverse order they were created in, when the statement (or expression?) ends. More specifically, a "destructor" is called for them, much like the destructor of a class object when it goes out of scope.

    It's possible only one temporary is made, or none. I don't actually know what the truth is, so I come to you :-) I had drawn the conclusion that ALL expressions discard their values in the end (the temporaries created) whether or not their result is used, but I could be--and probably am--wrong about that, too. This might at least explain why an l-value reference cannot bind to something like 5 + 5, but an r-value reference can, one of the reasons I was curious about how expressions are carried out by the machine.

    • Alex

      You're on the right track. Expressions do create temporary values that are discarded if nothing is done with them. However, expressions do have specific orders in which they are evaluated -- we cover this in lesson 3.1.

      In the above case, y + z are evaluated first, producing temporary rvalue 25. Then operator= is called, and that value of 25 is assigned to variable x. Done.

      • Alfred O.

        Ah! I meant the operands themselves may not evaluate in a specified order (well, I mean not specified by the C++ language, so it is left up to the designers of the compiler itself to decide, or maybe the compiler chooses based on what is more efficient).

        I read something out of curiosity, which led to one thing, which led to another thing, and now I'm so far off my tracks I can't remember how I got where I'm at, or where I was. I believe it was a wikipedia article on "Sequence Points," something I saw and took note of. According to that, all operands of expressions, and arguments of functions--which I guess could be thought of as arguments of the function call operator ()--aren't guaranteed to evaluate in any specific order. Which is probably why something like:

        function(i = 5 + x, x = i++, ++y = y - x * i); // Who knows what the heck you'll get???
        index[i++] = ++i; // I wouldn't dare to do this anyway

        Some places call it "Order of Evaluation" instead of "Sequence Points." And even more confusing, I stumbled across this article while researching it: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0145r1.pdf

        Looks like they're trying to change this issue in C++17. If they do, I'll have to get used to that right after learning about it, LOL. I guess it's better they keep improving C++, it's probably worth the headache.

        P.S. When the assignment operator = assigns a value, is this value copied into the variable, or is it "bound" like a reference? Or is the temporary value created by evaluation always discarded, regardless of what happens at the end of an expression?

        Also, thank you for responding to me. And thank you for this web site! It's made learning the language so much easier. I bought a few of the recommended books (recommended from Stack Oveflow) and they don't really go out of their way to explain much. After going through a few chapters on this site, and THEN reading the book (not all of it, but one day), the book makes perfect sense, so that tells you a whole lot about how good this site is.

        • Alex

          Don't worry about sequence points for now. As long as you avoid using a variable with side effects applied more than once in a single expression, you'll be fine. I cover side effects in more detail in chapter 3.

          When you use assignment, the value is copied. C++ does support references as well -- we also talk about those in chapter 6.

          Any temporary values from expressions are discarded at the end of the expression. Whether you copy those values to a variable (via assignment or initialization) is your choice. We talk more about initialization and assignment in chapter 2.

          I think it's great that you're going off the rails and doing your own explorations. Just note that a LOT of your questions are probably covered in future lessons, so keep reading!

          The reason this site exists is because I found most books to be very difficult to understand if you didn't already know what they were talking about. I try to assume you don't know anything here. Additionally, this site has gone through a lot of refinement based on reader questions, thoughts, and feedback. That's one advantage an online site has over a book!

  • Alfred O.

    Alex, can you explain what a "Primary Expression" is? It's a term I've started to run into since taking a break from learning C++. I come back, and now I'm seeing "Primary Expression," "Postfix Expression," and "l-value" and "r-value" has been appended with "x-value," "gl-value," and "pr-value." It's like I fell through a hole in time-space and woke up in a different dimension. What the heck does all this new stuff mean? Things used to be so simple!

    • Alex

      Yeah, C++11 kind of made a mess of things due to move semantics. From http://en.cppreference.com/w/cpp/language/value_category:

      a glvalue is an expression whose evaluation determines the identity of an object, bit-field, or function
      a prvalue is an expression whose evaluation either computes the value of the operand of an operator (such prvalue has no result object), or initializes an object or a bit-field (such prvalue is said to have a result object). All class and array prvalues have a result object even if it is discarded.
      an xvalue is a glvalue that denotes an object or bit-field whose resources can be reused
      an lvalue is a glvalue that is not an xvalue.
      an rvalue is a prvalue or an xvalue.

      There are a bunch of examples of each on that page.

      But honestly, I wouldn't sweat about any of them right now except lvalue and rvalue. You can learn about glvalues, prvalues, and xvalues if and when they become useful in some context that's relevant to something you need to know.

      • No wonder I'm finding it difficult re-learning C++ using Visual Studio 2017. Last time I touched it was pre-Windows (Borland Turbo C and Turbo C++) a hell of a lot has changed since then.  In fact I seem to recall having a listing of the C++ code for the 1st version of Windows somewhere.....

  • Sam

    Thanks for the tutorial. Very useful!

  • Tristan Gybels

    Hey, Alex!

    Try to make a book of this!
    I would buy this big time! I'm sure you'll make some big money with it ;)
    You only have to cut 'n paste everything.

Leave a Comment

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