What Is Activation Record in the Context of C and C++

What is activation record in the context of C and C++?

An activation record is another name for Stack Frame. It's the data structure that composes a call stack. It is generally composed of:

  • Locals to the callee
  • Return address to the caller
  • Parameters of the callee
  • The previous stack pointer (SP) value

The Call Stack is thus composed of any number of activation records that get added to the stack as new subroutines are added, and removed from the stack (usually) as they return.

The actual structure and order of elements is platform and even implementation defined.

For C/C++ programmers, general knowledge of this structure is useful to understand certain implementation features like Calling Conventions and even why do buffer overflows allow 3rd party malicious code to be ran.

A more intimate knowledge will further the concepts above and also allow a programmer to debug their application and read memory dumps even in the absence of a debugger or debugging symbols.

More generally though, a C/C++ programmer can go by a large portion of their hobbyist programming career without even giving the call stack a moments thought.

C++ Stack Frame/Activation Record and 'this' pointer

this only exists within a class or struct. It does not exists within a free function.

this points to the object whose member function is called.

In your case, this points to an instance of Example and thus the type is Example*

I don't know the term ActivationRecord. C++ doesn't know the concept of a function stack, that's just an implementation detail.

Why is dynamic link required in function activation record? (in static scoped language)

I will use this nomenclature which is more familiar to me:

Activation record: Stack frame

Dynamic link: [saved] frame pointer

So, I interpret your question as: Why are frame pointers needed?[1]

A frame pointer is not required.

Some compilers (e.g. Green Hills C++, GCC with -O2) don’t usually generate one or can be asked not to generate it (MSVC, GCC).

That said, it does of course have its benefits:

  • Easy traversing of the call stack: generating a stack trace is as easy as traversing a linked list where the frame pointer forms the head. Makes implementing stack traces and debuggers much easier.

  • Easier code generation: stack variables can be referenced by indexing the frame pointer instead of the all-the-time-changing stack pointer. The stack pointer changes with each push/pop, the frame pointer stays constant within a function (between the prologue/epilogue)

  • Should things go awry, stack unwinding can be done using the frame pointer. This is how Borland’s structured exception handling (SEH) works.

  • Streamlines stack management: Particularly implementations of setjmp(3), alloca(3) and C99-VLA may (and usually do) depend on it.

Drawbacks:

  • Register usage: a x86 got only 8 general purpose registers. one of these would need to be dedicated fully for holding the frame pointer.
  • Overhead: the prologue/epilogue is generated for every function.

But as you noticed, a compiler can generate perfectly fine code without having to maintain a frame pointer.


[1] If that's not what's meant, please elaborate.



Related Topics



Leave a reply



Submit