-7

One of my students asked about the lifetime of a local variable in C++. I told him that it is limited to the body of that function in which it was used but after I was amazed after I was shown the following.

It declares two functions fun() and fun2() and declares int i in both functions. According to my concept both int i of fun() and fun2() will be saved as different variables in memory but both function gives me same memory address. Need help with that.

void fun()
{
    int i;
    std::cout << &i << std::endl;
}

void fun2()
{
    int i;
    std::cout << &i << std::endl;
}

void main()
{
    fun2();
    fun();
}
YSC
  • 38,212
  • 9
  • 96
  • 149
rafiyz
  • 23
  • 3
  • 6
    Both `i`s exist at different times, they *can* share the same address location. This is undefined behavior, the variables may or may not have the same address. It helps to consider how a stack works. Try again with `fun()` calling `fun2()` and you will certainly see that they no longer share an address. – François Andrieux Mar 13 '17 at 14:58
  • 10
    `void main` is not legal C++. You should get a good C++ book and do less guessing about the language, *especially if you are supposed to teach it!* – Baum mit Augen Mar 13 '17 at 14:58
  • There is no rule that says two different functions cannot allocate a variable at the same position on the stack (they do so at different times). So it happens to be at the same location but that doesn't mean much. – Philipp Mar 13 '17 at 15:00
  • 2
    @FrançoisAndrieux not undefined behaviour, but an unspecified value for sure. – Quentin Mar 13 '17 at 15:02
  • @Quentin Thank you, you are correct. But it's too late to edit the comment now. – François Andrieux Mar 13 '17 at 15:04
  • 2
    It looks like you might benefit from reading a book on C++ or attending a basic C++ course. This is a pretty fundamental case. – Bartek Banachewicz Mar 13 '17 at 15:04
  • The life-time (aka storage duration) of a local variable depends on its storage class (hope that's the same terminus in C++ as in C). You mean _automatic_ variables? And the standard does not say how/where variables are to be stored. That is left to the implementation. – too honest for this site Mar 13 '17 at 15:07
  • 4
    In addition to all the other comments: "it is limited to the body of that function in which it was used" - Nope. Wrong. Fail. It is limited to the **block** in which it is used. I am appalled that someone who is *teaching* the language would get that wrong. – Martin Bonner supports Monica Mar 13 '17 at 15:08
  • @MartinBonner: Also wrong. The _storage duration_ is limited to the block it is _defined_. – too honest for this site Mar 13 '17 at 15:09
  • Downvoters: Please consider whether this is a good question or not. Don't use down votes to punish the OP for having so little knowledge of the subject he is supposed to teach. – Martin Bonner supports Monica Mar 13 '17 at 15:10
  • BTW, variables do not *need* to be stored in memory. The compiler is allowed to assign variables to registers and thus no memory is occupied. However, the rules change when using pointers or taking the address of a variable. When taking the address of a variable, it should have a memory address because registers usually don't have addresses. – Thomas Matthews Mar 13 '17 at 15:11
  • 2
    @MartinBonner: Downvotes are also allowed if y question does not chow research effort. As you wrote: someone teaching a language should be able to find such obvious things like the standard. It might differ if one of the students would have asked. – too honest for this site Mar 13 '17 at 15:11

3 Answers3

7

one of my students asks the question that what is the life of local variable in c++. i told him that it is limited to the body of that function in which it was used

This is inaccurate. The lifetime of an automatic variable extends until at the end of the scope where the variable is declared. For example, a variable in a compound statement (also known as block) extends until the end of that compound statement whether that compound statement is the body of the function, or nested within a function body.

Example:

void foo() {
    {
       int i;
    }
    // lifetime of i has ended, but function hasn't returned yet
}

Each scope has different rules for how far they extend. For example, the scope of function arguments extend until the end of the function. The scope of names declared in sub-statements of a control structure (like a loop or a conditional statement) extend until the end of the control structure.

Static local variables have static storage duration and their lifetime is not bound by the scope of their declaration.

i declared two functions fun() and fun2() and declare int i in both functions. according to my concept both int i of fun() and fun2() will be saved as different variables in memory but both function gives me same memory location

They are "saved as different variables", but that has nothing to do whether the variables will be stored in a separate memory location.

In fact, according to your concept, the lifetime of the local variable of fun has ended, so there is no reason why the local variable of fun2 couldn't use the same memory where the - now destroyed - object used to be.

eerorika
  • 232,697
  • 12
  • 197
  • 326
  • You should clarify about what "current block" means. – too honest for this site Mar 13 '17 at 15:13
  • @Olaf by "block" i mean "compound statement", and by "current" I mean "that compound statement, within which the variable was declared". Edit: Answer reworded – eerorika Mar 13 '17 at 15:18
  • A block and a compound statement are very different grammatical structures. So it does not apply to a function body or a block? (well, I know the answer, you just should get the terms right for such a question.) – too honest for this site Mar 13 '17 at 15:21
  • @Olaf block is a compound statement is block. The standard defines them having equivalent meaning. – eerorika Mar 13 '17 at 15:25
  • My bad, you are correct, I confused compound statement with iteration etc. statement. Anyway, "surrounding block" is wrong. It would have to be "associated block", to cover variables defined in the first epression of a `for` loop (there is a reason the standard has not one single sentence for that matter:). – too honest for this site Mar 13 '17 at 16:14
  • @Olaf I wanted to keep my answer simple, but you've forced me to introduce scopes :) There is always a surrounding block for static local variables. I don't think it's very relevant whether they are not bound by the control structure they are in, or not bound by the surrounding block, since they are not bound by scope at all. – eerorika Mar 13 '17 at 16:28
  • I did not mean static variables; they have a different lifetime/storage duration, of course. OP seems to be after automatic variables primarily. But yes, it becomes lengthly. And is mostly just citing the standard, OP could have looked up himself. – too honest for this site Mar 13 '17 at 16:30
  • @Olaf I see. You criticized my use of "surrounding block" which I used strictly in the context of static local variables. – eerorika Mar 13 '17 at 16:33
  • There is no static local variable, though. Neither in the question, nor your answer. That would be wrong for e.g. `for` or `if` statement. – too honest for this site Mar 13 '17 at 16:37
  • @Olaf there is no static local variable in the code example of the question, but the question itself wasn't explicitly limited to non-static local variables, but local variables in general. Since static variables can also be local variables, my answer does explain that they are different. But I felt that no code example or further explanation is necessary, since I suspect that OP is more interested in non-static local variables. "Surrounding block" would be wrong for non-static variables in control structures, but that is why I never used "surrounding block" to refer to those. – eerorika Mar 13 '17 at 16:41
  • Yes, I know OP uses the term "local". but considering the rest of the question, I strongly doubt he is aware it covers automatic and static variables. (that is a common error by beginners). And yes, I think that's exactly what I wrote before :-) – too honest for this site Mar 13 '17 at 17:23
5

According to my concept both int i of fun() and fun2() will be saved as different variables in memory.

fun::i and fun2::i are indeed two different variables, with different scope and storage duration. The fact that the compiler choose to put them at the same virtual memory address changes nothing.

But both function gives me same memory location.

It was able to do so because after fun2() returned, the stack space it used (the int fun2::i) is available and fun::i can reuse that space.

To summarize, please see this answer from SO:

What is Scope?

Scope is the region or section of code where a variable can be accessed.

What is a lifetime?

Lifetime is the time duration where an object/variable is in a valid state.

For, Automatic/Local non-static variables Lifetime is limited to their Scope. In other words, automatic variables are automatically destroyed once the scope({, }) in which they are created ends. Hence the name automatic to begin with.

Community
  • 1
  • 1
YSC
  • 38,212
  • 9
  • 96
  • 149
  • Not my downvote. Just that: "life time" or storage duration (the latter is the C terminology, not sure about C++). – too honest for this site Mar 13 '17 at 15:16
  • @Olaf Thanks. According to cppreference, _[storage duration](http://en.cppreference.com/w/cpp/language/storage_duration)_ is valid C++ terminology. – YSC Mar 13 '17 at 15:28
  • There is a subtle difference. *"Storage duration is the property of an object that defines the minimum potential lifetime of the storage containing the object."*. – eerorika Mar 13 '17 at 15:33
  • @YSC: It might be correct, but cppreference is not an authoritative reference. That would be the standard. – too honest for this site Mar 13 '17 at 15:42
  • @user2079303: That's what OP asks for. "difference" - compared to what? I don't think life-time is a standard term. – too honest for this site Mar 13 '17 at 15:42
  • @Olaf I refer to the difference of the terms *"lifetime"* and *"storage duration"* in standard nomenclature. They are subtly different i.e. not equivalent. But not in a way that is relevant to this question (in my opinion). – eerorika Mar 13 '17 at 15:45
  • @user2079303: Ah, ok, temporary objects have only a lifetime, but no storage duration, it is the broader term (at least in C; I'm not familiar with the C++ standard, hope it's the same). – too honest for this site Mar 13 '17 at 15:50
  • @Olaf C++ has constructors and destructors. Essentially storage duration determines whether there is memory allocated for the object, lifetime begins when the object is fully initialized with constructor calls, if any. – eerorika Mar 13 '17 at 15:55
3

The memory address in fun2 is available for reuse after fun2 is over.

That memory location happens to be reused in fun.
(there is no guarantee that it will be the same address or a different address; either is possible)

Do you think there is a guarantee that a memory address will NEVER be re-used anywhere, ever again? Wouldn't your computer run out of memory that way??

If you want to see separate addresses used, make fun2 call fun:

void fun2()
{
int i;

cout<<"This is the address in fun2:" << &i <<endl;
fun(); // This will show a different address.
}
abelenky
  • 63,815
  • 23
  • 109
  • 159