10.5 — Returning values by value, reference, and address

In the three previous lessons, you learned about passing arguments to functions by value, reference, and address. In this section, we’ll consider the issue of returning values back to the caller via all three methods.

As it turns out, returning values from a function to its caller by value, address, or reference works almost exactly the same way as passing arguments to a function does. All of the same upsides and downsides for each method are present. The primary difference between the two is simply that the direction of data flow is reversed. However, there is one more added bit of complexity -- because local variables in a function go out of scope and are destroyed when the function returns, we need to consider the effect of this on each return type.

Return by value

Return by value is the simplest and safest return type to use. When a value is returned by value, a copy of that value is returned to the caller. As with pass by value, you can return by value literals (e.g. 5), variables (e.g. x), or expressions (e.g. x+1), which makes return by value very flexible.

Another advantage of return by value is that you can return variables (or expressions) that involve local variables declared within the function without having to worry about scoping issues. Because the variables are evaluated before the function returns, and a copy of the value is returned to the caller, there are no problems when the function’s variable goes out of scope at the end of the function.

Return by value is the most appropriate when returning variables that were declared inside the function, or for returning function arguments that were passed by value. However, like pass by value, return by value is slow for structs and large classes.

When to use return by value:

  • When returning variables that were declared inside the function
  • When returning function arguments that were passed by value

When not to use return by value:

  • When returning a built-in array or pointer (use return by address)
  • When returning a large struct or class (use return by reference)

Return by address

Returning by address involves returning the address of a variable to the caller. Similar to pass by address, return by address can only return the address of a variable, not a literal or an expression (which don’t have addresses). Because return by address just copies an address from the function to the caller, return by address is fast.

However, return by address has one additional downside that return by value doesn’t -- if you try to return the address of a variable local to the function, your program will exhibit undefined behavior. Consider the following example:

As you can see here, value is destroyed just after its address is returned to the caller. The end result is that the caller ends up with the address of non-allocated memory (a dangling pointer), which will cause problems if used. This is a common mistake that new programmers make. Many newer compilers will give a warning (not an error) if the programmer tries to return a local variable by address -- however, there are quite a few ways to trick the compiler into letting you do something illegal without generating a warning, so the burden is on the programmer to ensure the pointer they are returning will point to a valid variable after the function returns.

Return by address was often used to return dynamically allocated memory to the caller:

This works because dynamically allocated memory does not go out of scope at the end of the block in which it is declared, so that memory will still exist when the address is returned back to the caller. Keeping track of manual allocations can be difficult. Separating the allocation and deletion into different functions makes it even harder to understand who’s responsible for deleting the resource or if the resource needs to be deleted at all. Smart pointers (covered later) and types that clean up after themselves should be used instead of manual allocations.

When to use return by address:

  • When returning dynamically allocated memory and you can’t use a type that handles allocations for you
  • When returning function arguments that were passed by address

When not to use return by address:

  • When returning variables that were declared inside the function or parameters that were passed by value (use return by value)
  • When returning a large struct or class that was passed by reference (use return by reference)

Return by reference

Similar to return by address, values returned by reference must be variables (you should not return a reference to a literal or an expression that resolves to a temporary value, as those will go out of scope at the end of the function and you’ll end up returning a dangling reference). When a variable is returned by reference, a reference to the variable is passed back to the caller. The caller can then use this reference to continue modifying the variable, which can be useful at times. Return by reference is also fast, which can be useful when returning structs and classes.

However, just like return by address, you should not return local variables by reference. Consider the following example:

In the above program, the program is returning a reference to a value that will be destroyed when the function returns. This would mean the caller receives a reference to garbage. Fortunately, your compiler will probably give you a warning or error if you try to do this.

Return by reference is typically used to return arguments passed by reference to the function back to the caller. In the following example, we return (by reference) an element of an array that was passed to our function by reference:

This prints:


When we call getElement(array, 10), getElement() returns a reference to the array element with index 10. main() then uses this reference to assign that element the value 5.

Although this is somewhat of a contrived example (because you can access array[10] directly), once you learn about classes you will find a lot more uses for returning values by reference.

When to use return by reference:

  • When returning a reference parameter
  • When returning a member of an object that was passed into the function by reference or address
  • When returning a large struct or class that will not be destroyed at the end of the function (e.g. one that was passed in by reference)

When not to use return by reference:

  • When returning variables that were declared inside the function or parameters that were passed by value (use return by value)
  • When returning a built-in array or pointer value (use return by address)

Mixing return references and values

Although a function may return a value or a reference, the caller may or may not assign the result to a variable or reference accordingly. Let’s look at what happens when we mix value and reference types.

In case A, we’re assigning a reference return value to a non-reference variable. Because giana isn’t a reference, the return value is copied into giana, as if returnByReference() had returned by value.

In case B, we’re trying to initialize reference ref with the copy of the return value returned by returnByValue(). However, because the value being returned doesn’t have an address (it’s an r-value), this will cause a compile error.

In case C, we’re trying to initialize const reference cref with the copy of the return value returned by returnByValue(). Because const references can bind to r-values, there’s no problem here. Normally, r-values expire at the end of the expression in which they are created -- however, when bound to a const reference, the lifetime of the r-value (in this case, the return value of the function) is extended to match the lifetime of the reference (in this case, cref)

Lifetime extension doesn’t save dangling references

Consider the following program:

In the above program, returnByReference() is returning a const reference to a value that will go out of scope when the function ends. This is normally a no-no, as it will result in a dangling reference. However, we also know that assigning a value to a const reference can extend the lifetime of that value. So which takes precedence here? Does 5 go out of scope first, or does ref extend the lifetime of 5?

The answer is that 5 goes out of scope first, then the reference to 5 is copied back to the caller, and then ref extends the lifetime of the now-dangling reference.

However, the following does work as expected:

In this case, the literal value 5 is first copied back into the scope of the caller (main), and then ref extends the lifetime of that copy.

Returning multiple values

C++ doesn’t contain a direct method for passing multiple values back to the caller. While you can sometimes restructure your code in such a way that you can pass back each data item separately (e.g. instead of having a single function return two values, have two functions each return a single value), this can be cumbersome and unintuitive.

Fortunately, there are several indirect methods that can be used.

As covered in lesson 10.3 -- Passing arguments by reference, out parameters provide one method for passing multiple bits of data back to the caller. We don’t recommend this method.

A second method involves using a data-only struct:

A third way (introduced in C++11) is to use std::tuple. A tuple is a sequence of elements that may be different types, where the type of each element must be explicitly specified.

Here’s an example that returns a tuple, and uses std::get to get the nth element of the tuple:

This works identically to the prior example.

You can also use std::tie to unpack the tuple into predefined variables, like so:

As of C++17, a structured binding declaration can be used to simplify splitting multiple returned values into separate variables:

Using a struct is a better option than a tuple if you’re using the struct in multiple places. However, for cases where you’re just packaging up these values to return and there would be no reuse from defining a new struct, a tuple is a bit cleaner since it doesn’t introduce a new user-defined data type.


Most of the time, return by value will be sufficient for your needs. It’s also the most flexible and safest way to return information to the caller. However, return by reference or address can also be useful, particularly when working with dynamically allocated classes or structs. When using return by reference or address, make sure you are not returning a reference to, or the address of, a variable that will go out of scope when the function returns!

Quiz time

Write function prototypes for each of the following functions. Use the most appropriate parameter and return types (by value, by address, or by reference), including use of const where appropriate.

1) A function named sumTo() that takes an integer parameter and returns the sum of all the numbers between 1 and the input number.

Show Solution

2) A function named printEmployeeName() that takes an Employee struct as input.

Show Solution

3) A function named minmax() that takes two integers as input and returns back to the caller the smaller and larger number in a std::pair. A std::pair works identical to a std::tuple but stores exactly two elements.

Show Solution

4) A function named getIndexOfLargestValue() that takes an integer array (as a std::vector), and returns the index of the largest element in the array.

Show Solution

5) A function named getElement() that takes an array of std::string (as a std::vector) and an index and returns the array element at that index (not a copy). Assume the index is valid, and the return value is const.

Show Solution

10.6 -- Inline functions
10.4 -- Passing arguments by address

301 comments to 10.5 — Returning values by value, reference, and address

  • Michael

    Hi Alex,

    I wonder why it is not allowed to return a literal by const reference since a const reference will extend the lifetime of a literal to match the conference.

    I think the answer lies in how function returns a value under the hood. And I have been pondering this a lot as well. I mean passing into a function several arguments is easier to conceptualize: parameters with local scope are initialized with the argument passed in.

    But how to conceptualize the return process is hard. For example,

    the function return 20 but where is it stored? We can only see a type information 'int' related to the return value without any identifier suggesting where the value is actually stored.

    As stated in 7.6a section, we get a copy of return 20. How do we access this copy? What's its identifier?

    I find this case easy to understand since I can say now 'oh the copy of 20 is copied again into a'.

    what if we just use test() alone like this?

    In this case, I speculate that test() itself is an identifier that has the copy of return value 20.

    I develope my speculation from that and maybe we now can see


    the test() here acts just as an identifier and the return type int becomes the type of this identifier. However, 20 here is of local scope so this may be very accurate.

    If I'm allowed to see it this way, then I'll see


    which seems totally fine to me. And that's why I don't understand why you can't return a literal by const reference.

    I did a little research and in
    I probably got something to patch up my approach.

    It says the compiler will create a temporary object to hold the literal and have the reference pointed to this temporary object.

    Then the approach would become something similar to this

    and temp will go out of scope after the function returns, which ends up with a dangling reference. This can explain why we can't return a literal by const reference.

    Sorry for my all over the place thought process.

    My question is that is it a practical way of seeing how function returns as above? And is the explanation for no return value by const reference developed from it accurate enough?

    • Alex

      A const reference can extend the lifespan of a temporary object, but only within the function in which it is declared. Const references can't extend the lifespan of temporary objects returned by reference (but they can for temporary objects returned by value, since the by-value temporary exists in the scope of the caller). This was apparently an arbitrary restriction to help keep compilers simpler. Otherwise you potentially have local variables that can outlive the scope in which they are defined.

  • Michael

    Hi Alex,

    I didn't expect this to output 10, but it does. My theory is x is a reference to b, and test returns a reference to x.

    When the function ends, x goes out of scope and get destroyed. So what test have returned will lose its reference to x. And it should be referring to some garbage now.

    Where is my train of thought wrong?

    • Alex

      If you think of references as "aliases for another variable", this becomes quite straightforward.

      When test(b) is called, x is a reference to b. Therefore, x can be treated as an alias to b. When the function returns, it returns x (by reference). Since x is an alias for b, we're essentially returning b. In other words, the return value of test() is the variable that was passed in. We passed in b, we got b back. And printing the value of b is 10.

      It doesn't matter that x was created and destroyed -- the underlying object being referenced (b) is still valid at the point where it was printed (b doesn't go out of scope until the end of main()), so we're fine.

  • Liam

    When passing an std::array to a function, you use the following:

    Do you have to specify the array length in the parameter? What happens if you don't know it?

  • Jaideep

    The above code gives a compiler error but if i comment out hey(a) and uncomment hey(k) it works perfectly fine.So what's wrong here?

    • Alex

      More type mismatches. First, let's tweak this so it's simpler:

      This works, because a decays to a pointer to an integer, which matches the function parameter. However, when the function parameter is a reference parameter, the array to pointer logic doesn't take effect. So although it seems like this should work:

      It doesn't, because a isn't converted into a pointer to an int, it's treated as the actual array. In order to pass an array to a function, you'll need to do this:

      Now you're telling the compiler that you're expecting a reference to the full array, which works since the typical array decay doesn't happen here.


    I think this is called a segmentation fault (correct me if I'm wrong). It ran fine on in Visual Studio 2017 w/o any errors or warnings. Output was 20. However, on the Linux machine, it gave me a segmentation fault error.

  • KnowMore

    Alex, I was revisiting some of the basics of C++, and, I found that when a variable is passed to a function's reference parameter, it doesn't show the effect of the reference in the variable on the same line being called ! What I'm trying to say is this :-

    operator(<<) executes in -> style,  not in <- ! So, It Should have updated the value of x accordingly, but, It Didn't!
    Is this behaviour due to Side-Effects?
    Waiting for your reply......
    Thanks In Advance :)

  • John Halfyard

    The mystery deepens... if I //comment out all the code and add a token command (see code) the application file reappears in the 'debug' folder.  When I reverse the process, the application file disappears.

    • Alex

      It's possible your virus scanner or malware detector is interfering. You might try disabling them and see if that fixes your issue... Outside of that, I'm as perplexed as you.

  • John Halfyard

    Update::  I checked out my earlier Projects from Chapters 1-6 (which run fine).  Noticed in the "Debug" folder there is an applications file.  But in the Chapter 7_4a_Q1 there is no applications file.  Not sure what I did here.

    • Alex

      Not clear on whether you were able to resolve this. Your code compiles fine for me, so something in your project must have gotten messed up. Easiest thing to do is just create a new one from scratch and paste your code in.

      • John Halfyard

        Alex... see my last comment.  Following your suggestion, I pasted the code into a new solution (naming it something else) and still my *.exe application is not being placed into the debug folder and I get the same error.

        I can run past chapter questions fine and when I check the application file is in the debug folder.

  • John Halfyard

    I get the following runtime error.  I don't think there's anything wrong with the code but this prompt happened after I mistakenly named a file "Chapter_7.4a_Q1".  When I deleted that folder and started over I get the following error:  "XXXXX.exe" is not recognized as an internal or external command.  

    Here's my code - was attempting Q1 in Section 7.4a

  • Viraj

    Hey Alex, really enjoying the tutorial so far! You've done some great work. :)
    Just a question:
    In the quiz question 4's answer,

    Is it necessary to put a const before the second int parameter? (Since we're passing it by value wouldn't it be kind of pointless to?)

    And if it's been done to ensure that length does not accidentally get changed in the function, why, in the answer to the third question (given below) is the same not done to x and y?

    Thanks for all the help!

    • Alex

      It's not necessary, but it is considered a best practice. It signals to other programmers (or our future self) that we don't intend for this value to change inside the function, and enlists the compiler's help in making sure we don't change it. Understanding what might change and what won't makes the purpose of the parameter, and the function itself, easier to understand.

      In the other example, x and y should similarly be made const for consistency with best practices. I've updated the answers accordingly. Thanks for pointing this out!

  • Mor

    Shouldn't the answer to 3 be

    Since otherwise you won't have anything to put into minOut and maxOut, unless you declare static variables in the function/return reference to global variables/allocate dynamic memory for the reference.

    • Alex

      Nope. I see what you're thinking. However, remember that assigning to a reference doesn't change the reference, it only changes the value that's being referenced.

      So when we say:

      We're not setting minOut to reference (local) variable x or y (which would be bad, as you noted), we're setting the value of the argument passed in for minOut to the value of x or y (which is fine).

  • :|

    What is the int& for? i dont understand the syntax for the functions, they have to be inside the parameter like (*array, &y) or they have to be out of the parameter and in the function declaration (int& functionName?) or both?

    What is the syntax for return values with adressess and references?

  • Alan

    Hello , Alex
    I have some problem with the return by address and reference

    Case 1

    int* allocateArray(int size)
        return new int[size];
        // why do u say the dynamically allocated memory does not goes out of the scope at the end of the block
           in which it is declared since it do really goes out of block of the the function allocateArray which means the pointer containing the address of dynamically allocated memory should be destroy resulting in undefined result?

    int main()
        int *array = allocateArray(25);

        // do stuff with array

        delete[] array;
        return 0;

    Case 2

    // Returns a reference to the index element of array
    int& getElement(std::array<int, 25> &array, int index)
        // we know that array[index] will not be destroyed when we return to the caller (since the caller
           passed in the array in the first place!)
        // so it's okay to return it by reference
        return array[index];

    int main()
        std::array<int, 25> array;

        // Set the element of array with index 10 to the value 5
        getElement(array, 10) = 5;
        std::cout << array[10] << 'n';

        return 0;

        what does it mean by (since the caller passed in the array in the first place)?Wont it reference to a garbage value when the block is exited?

    Your help is greatly appreciated.

    • Alex

      1) Dynamically allocated memory persists until explicitly deleted by the programmer.
      2) No, because the caller passed in the array, we can reasonably assume that when a result from the array is returned back to the caller that it will still exist.

  • Zoran

    Hello, Alex,
    In this lesson you say:

    When to use return by reference:
      *  When returning a large struct or class that has scope outside of the function

    Shouldn't it actually be:

      *  When returning a large struct or class that has duration outside of the function

    So, isn't the correct word there "duration", not "scope"?
    I might not be right, as I'm just learning C++ (although not new in programming). But if I got everything right after I had read the tutorial up to this point, it should be "duration".


  • jenifer

    It must print some garabage value, but how it works?

    • Alex

      Returning a reference (or pointer) to a local variable results in undefined behavior. That "undefined behavior" can manifest in any number of ways: It may work fine all of the time. It may work fine some of the time and not others. It may cause your program to crash. It may look like it's working but mess up something else. It may work on some compilers and not others. It may work until you change some other line of code. With a little digging, we could probably determine why this particular case is working like it is, but it's not worth it. You're violating the rules of C++, and understanding how it's working in unsupported cases isn't a good use of our time. :)

  • David

    On number 5 and 6 of the quiz, why was 'const int' not used for length and index? Since the functions would not modify these values, shouldn't const be preferred?

    • Alex

      Yes, slightly preferred, since then we can enlist the compiler to assist in ensuring we don't accidentally change these inside the function.

      However, because these are pass by value parameters, even if the function does change them, the argument won't be changed, so the risk is pretty minimal. Nevertheless, I'll update the reference answers.

  • Milos

    Can you explain a little bit question number 5 in quiz? Thanks Alex!

    • Alex

      Is there something in particular you find confusing?

      • Milos

        I made some effort and now i understand all the quiz questions. But Alex, at part "Mixing return references and values" in example B and C, what do you mean by "rvalue", and in C how can a const variable extend the life of return value, btw how can references hold literal values?
        A lot of awkward questions but i truly want to understand this part, so Alex i hope u can help me with it. Thanks!

        • Alex

          > what do you mean by "rvalue"

          An rvalue is a literal or a temporary/anonymous value or something that doesn't have a permanent memory address.

          > in C how can a const variable extend the life of return value,

          The scope of the returned value is extended so that it doesn't go out of scope until the reference does.

          > btw how can references hold literal values?

          Const references have special logic that let them point to literals and other rvalues. Without this, references would be a pain because you'd only be able to pass lvalues to them, never a literal or temporary result of some expression...

  • Martin

    I have a question concerning the quizzes. In almost all examples the int parameter is passed without the const, e.g. the length in 4) and 5).
    Why is that so? Wouldn't it be safer to add the const keyword to prevent the programmer from actually changing it?

    Thanks in advance for the answer.

    • Alex

      Yes. If you don't expect the function to change the value of the parameter, it's safer to make the parameter const.

      This is particularly important for pointer and reference parameters, because inadvertently modifying the parameter can modify the underlying argument.

      However, in practice, use of const is often omitted for variables passed by value, since in the worst case, if the function changes the value, it's only changing a copy. There's no benefit to not using const in such a case, it's just bad habit that tends to be of low consequence.

      • Trevor

        Hi Alex
        You say that there is no benefit to not using const in such a case (passing by value). However in Quiz 1, adding a const would prevent you from doing this:

        as the compiler will reject value-- if value is marked const.
        Do you consider this to be a less desirable way of implementing this function because you have to leave out the const?

        • Alex

          Yes, this is totally fine. My third paragraph wasn't meant to preclude the first -- If your function is intending to change the value of the parameter, clearly it can't be const.

  • Anonymous

    I have a question about this line in your tutorial --

    int main()
        int value = returnByReference(); // case A -- ok, treated as return by value
        int &ref = returnByValue(); // case B -- compile error
        const int &cref = returnByValue(); // case C -- ok, the lifetime of return value is extended to the lifetime of cref
    In case A, we’re assigning a reference return value to a non-reference variable. Because value isn’t a reference, the return value is copied into value, as if returnByReference() had returned by value.

    Now my question is -- Since The reference of x returned "is copied" into value --- will modifying "value" in the program modify "x" the variable?

  • Perry Frimpong Mensah

    I am making a program for riddles and say if the answer to a riddle is age, not everyone would write age. Some might write Age or even AGE. How do I make all of these answers valid and not just one of them

    • Alex

      Generally the best thing to do in such a case is convert the user input to lower case before checking against the correct answer (which should also be lower case).

      • Max

        Hi Alex, I've been wondering about this too. How do you recommend going about this? I searched and saw a few options like tolower(), but I don't know if that's the best or you recommend something else.

        • nascardriver

          Hi Max!

          std::tolower looks good but might be a little too much for the task you're working on.
          Assuming your program only allows latin characters you could loop through the input string and add 0x20 to every upper case letter to convert it to lower case (A char is a number).

          EDIT: Whoops, didn't see you're not OP. This method might apply to your case too so I'm gonna leave it here.

          • Max

            I did think about an ASCII method but that didn't seem portable. Even found a comment online that said "    
            Every time you assume characters are ASCII, God kills a kitten. :(". Made me laugh.

            Thanks for the method though! Should be fine for most cases.

        • Alex

          Yes, you can use std::tolower().

          Here's how to apply it to every character in a std::string:

  • Happy Holidays, everyone!

    I am finding this C++ tutorial site very useful. Complex concepts are explained very lucidly, and the exercises reinforce the core material.

    My only suggestion would to perhaps provide a page that links to various chapters/sections in the course, and serves as a fast-track for people who already know programming in another language.

    I use this site with AdBlocker, so the ads don't compete for my attention. I have chosen to support Alex directly, and encourage others to do so.

    Thank you, Alex!

  • Gajendra Gulgulia

    i come from a mechanical engineering background from India and have enrolled for computational science engineering at the Technical University of Munich. We have a course in advanced programming which considers that one already knows the basics of C++ and further advanced topics in C++ are to be built upon in the advanced course.

    Without any precursor, the course started dealing with Classes, pointers and what not in OOP using C++ , and I sat like a dumbass through the lectures, until in one of the tutorials, the tutor mentioned in the slides to learn from

    Here I am already through this section and hope to catch up with the missed programming tutorials in a few weeks.

    Thanks so much for saving my ass! :)

  • Matt

    Under section "Return by address", second paragraph, you wrote:

    "However, returning by address has one additional downside that pass by reference doesn’t -- you can not return local variables to the function by address."

    I think it would be better if you replaced "function" with "caller".

  • Kılıçarslan

    I have two questions.Returning local variables by reference or by address never gives me a compile error,it(VS) only warns me about it.Doest it mean processing system still didn't allocate a memory for the now empty memory,so it doesn't give me a compile error?

    Second question is how

    differs from

    I tried nearly every possible combination to get an error where "const" is used for function definitons or declarations.

    • Alex

      1) I don't understand what you are asking about re: returning local references or addresses.
      2) The top example returns a const reference whereas the bottom example returns a non-const reference. So in the top case, you couldn't do something like this:

      But in the bottom case you could.

      • Kılıçarslan

        Thanks for clarifying me about second one.For the first one,consider this:

        Now if I compile,compiler only warns me about returning address of local variable but in run-time I never get an error if I use that returned reference of local variable.Does this mean,system has nothing placed in the memory address of the variable?

        • Alex

          It means that the reference returned by function doubleValue() is aliasing memory that is no longer allocated for variable value.

          Accessing that reference will therefore have an undefined result -- it might work for a little while. It might stop working after a little while (perhaps when another function is called and the memory is reused). It might crash your program.

  • Amol

    Hi Alex,

    This is a wonderful site! I am really enjoying learning C++ thanks to you!

    I have one question though.

    I am not sure why I am getting below output for the give code:
    From what you explained above, I shouldn't have gotten correct answer, but I do get correct answer every time I run this code.
    And what's more surprising is that the pointer named 'yPtr' is pointing to different address before and after returning the value!
    Can you please provide your insights?


    • Alex

      I didn't say you wouldn't get the correct answer. I said the result would be undefined. It might work, or it might not, depending on what C++ is doing behind the scenes, and what else your program is doing, and any number of other things.

      You're not getting the same address because you're not printing the address of the same variable. In function doubleit2(), you're printing the address of doubleit2's variable y (through the pointer yPtr). In function main(), you're printing the address of main's variable y.

      • Amol

        Ok. Thanks Alex.

        But they both are pointing to the same value (i.e. 6) in memory right?

        Also, is there any tool or something which can help us visualize memory allocation in c++ ?

        • Alex

          They may or may not. As I said, the results are undefined.

          When you did this:

          You're saying "instantiate a new variable named y and initialize it with a copy of the value that the pointer returned from function doubleIt2 is pointing to".

          If the pointer returned from doubleIt() was pointing at value 6, that value 6 would get copied into main's variable y. In that case, both y's have value 6, but they do not occupy the same memory address.

          However, because you're returning a pointer to a value that's goes out of scope before you dereference it, who knows what value will actually be returned. Probably 6, but it's possible that when doubleIt2() goes out of scope and local variable y is destroyed that some other value could be put in that memory address.

          There may be tools to help visualize such things but I'm not aware of them.

  • Rahul Choubey

    Hi Alex,

    I tried passing an address of local variable from a function. And it compiles fine (no warning) and runs fine in Visual Studio 2015:

    I thought,  this will not work as local variable die out and deferencing should give some garbage value, if not some runtime exception. What's wrong?

    • Alex

      Just because the compiler will let you do something doesn't mean you should do it.

      You're right, this will not work, because the local variable will be destroyed, so the memory address returned will be left as a dangling pointer. Accessing that memory address will have undefined results (sometimes it might work, sometimes it might crash, sometimes you might get a different value back, etc...)

  • Anonymous


      In the example that was mentioned (Case A, Case B and Case C), can it be thought of as implicit type conversion done by the compiler?

    const int (high)
    int &   (low)  

    Assuming the compiler implicitly converts to the type above (if need be), and the reason for error being the compiler could not convert it implicitly (in Case B).

    Just like in the case of :

    long double (high)
    unsigned long long
    long long
    unsigned long
    unsigned int
    int (low) // * taken from chapter 4.4

    Does it work that way?

    • Alex

      Not really, no. :) It's more that the language has specific rules about what happens when you mix (const/non-const) references and non-references.


    I'm curious about function declaration and return syntax of reference.

    When it come to return by value you wrote,

    From function declaration, 'int' means this function would return int type value. In the function local variable 'value' is an int type variable.(which is returned)

    However when it comes to return by reference it seems little bit strange. You wrote,

    From function declaration, "int&" means this function would return reference type. However inside the function you returned "static int" type variable 'x'. So could you return "int" type as a "reference"??

    Shouldn't we have to add another variable y which is an reference variable and return y? which looks like this.

    • Alex

      Remember that a reference is just an alias for a variable. So when we return x and the return type is a reference to an int, the compiler knows that we're intending to return a reference to that local x variable. We don't explicitly have to declare a reference version of x first and return that.

  • Chris


    i think we should return built-in array by address because at return by reference section you said don't return by reference built-in array, but at the above example at return by reference section and quiz number 5 you use return by reference for returning built-in array element. i am confuse with that, so we should use return by address or return by reference?

    Thank you.

    • Alex

      C-style arrays decay into pointers, so when we pass the entire array (either to a function, or as a return value), we typically do so by address.

      However, when dealing with individual array elements, it's easier to pass or return them by reference. Remember that operator[] (which you typically use to get the specific element of the array) does an implicit dereference, so you have an actual value to pass or return, not a pointer to it.

  • mrlinh

    I thank admin, knowledge is too wonderful for beginners, let me ask how original do so?

Leave a Comment

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