Block scope and Context of local variables

I recently came across some unusual code. I find it to be buggy at worst and risky at best. Any comments?

void TestFuction(int testValue)
{
char *testPtr = NULL;
if (testValue == 1)
{
myStructure aStructure;
testPtr = (myStructure *)&aStructure;
}
OtherFunction(testPtr); // where OtherFunction will write
// to the address in the pointer if it is not NULL
}

I posit that since "myStructure" has block scope, it could be out of context outside of it's block. The original author of the code posits that ALL local variables remain in context within the function they are declared in even outside of their own block.

Agree? Disagree?

Thanks.
The author has clearly misunderstood how scope works in C++. You're correct - at the end of the block, aStructure drops out of scope, and the memory for it is reclaimed for other uses. After that, testPtr is pointing to unreserved memory, resulting in undefined behaviour.

By the way, when posting code, please use code tags, to make it readable:

http://www.cplusplus.com/articles/z13hAqkS/
Apologies, this was the first time I have posted a question on this forum. I agree with your analysis MikeyBoy but since I've been unable to find a qualified reference stating that the memory is returned to the stack at the end of the block, I haven't been able to justify my position. I attempted to prove it with a debugger but the version I used wouldn't reveal current stack pointers. The strangest thing is that the actual code apparently works - there is no memory problem. This particular compiler (tried with a few different versions of GCC) seems to be allocating the structure at function entry and de-allocating at function exit. In any case, thank you for your comments. Here is the same code with code tags :

1
2
3
4
5
6
7
8
9
10
11
void TestFuction(int testValue)
{
   char *testPtr = NULL;
   if (testValue == 1)
      {
         myStructure aStructure;
         testPtr = (myStructure *)&aStructure;
      }
   OtherFunction(testPtr); // where OtherFunction will write
                                        // to the address in the pointer if it is not NULL
}

The strangest thing is that the actual code apparently works - there is no memory problem. This particular compiler (tried with a few different versions of GCC) seems to be allocating the structure at function entry and de-allocating at function exit.


Undefined behaviour is undefined. It might seem to work. It might immediately clear that memory. It might make your computer explode into a million fragments. It's undefined behaviour.

I find it hard to believe that any credible textbook on C++ wouldn't explain that stack variables are only valid within the scope in which they're defined.

EDIT: The following Wikipedia article discusses this:

https://en.wikipedia.org/wiki/Automatic_variable

I know Wiki isn't considered authoritative, but there might be some references from that article you can follow
Last edited on
> This particular compiler (tried with a few different versions of GCC) seems to be
> allocating the structure at function entry and de-allocating at function exit.

If the constructor and destructor of myStructure has no observable side-effects, the 'as-if' rule allows the implementation to do so.
http://en.cppreference.com/w/cpp/language/as_if

Try this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <iostream>

struct myStructure
{
    myStructure() { std::cout << "\t*** myStructure::constructor\n" ; }
    ~myStructure() { std::cout << "\t*** myStructure::destructor\n" ; }
};

int main()
{
   {
       std::cout << "entered a block-scope, creating an object\n" ;
       myStructure aStructure ;
       std::cout << "just before exiting block-scope\n" ;
   }
   std::cout << "exited block-scope\n" ;
}

http://coliru.stacked-crooked.com/a/f1e8b402eb755a37


> I've been unable to find a qualified reference stating that
> the memory is returned to the stack at the end of the block

C++ does not use terms like 'stack variable' or 'return memory to the stack'; the life-time of objects is specified in terms of an abstract concept called 'storage duration'. The standard is only concerned about the lifetime of an object (and the duration for which the storage for an object would be available).

For objects with automatic storage duration, the storage for the object is required only from the beginning of the enclosing code block and this storage can be deallocated or re-used on exiting from the code block. In practice, most implementations use the run-time stack for this kind of reclaimable storage; but that is technically an implementation detail.

This is what the IS has to say about the life-time of objects with automatic storage duration:
Block-scope variables not explicitly declared static, thread_local, or extern have automatic storage duration. The storage for these entities lasts until the block in which they are created exits.
...
Variables with automatic storage duration are initialized each time their declaration-statement is executed. Variables with automatic storage duration declared in the block are destroyed on exit from the block.
Topic archived. No new replies allowed.