Hello there.
I don't know if this should actually be posted in any of the C/C++ forums, but it is mainly an Assembly question so I take my chances here.

In C/C++ it is possible to declare local variables as:

if(statement){
    int var;
    // Use of the variables
}else{
    // Not using var
}

Compared to

int var;
if(statement){
   // Use of the variable
}else{
   // Not using var
}

But when we in class learn to translate C into assembly we have to declare all variables in a prologe (using LEAS). So my question is how the above examples would translate into assembly, is there any difference?

Dani AI

Generated

Short answer: in most cases there is no observable difference in the generated assembly just because you wrote a local inside a brace pair instead of at the top of the function. As noted, the compiler looks at the whole function and decides what storage is actually needed. What matters for the emitted code is variable lifetime, whether the address is taken, whether the variable is volatile, and whether the optimizer can keep the value in a register or eliminate it entirely.

A few concrete rules that change code generation: (1) debug builds or -O0 usually reserve a fixed stack frame in the prologue for easier debugging; (2) optimized builds often allocate nothing on the stack for trivially used locals and will reuse one stack slot for several non-overlapping lifetimes; (3) VLAs or runtime alloca require runtime stack adjustments; (4) taking a local’s address or marking it volatile forces memory storage; (5) in C++ an object with a non-trivial destructor must have destructor-call code emitted at scope exit, so placing it in an inner block affects when that code runs. Calling conventions and alignment rules can also change the size/layout of the frame (different ISAs use different stack-adjust instructions — e.g., LEAS on some 68k code versus SUB/ENTER on x86).

Practical check: as suggested, emit and compare assembly for both optimized and unoptimized builds (and for cases that take the address, use a VLA/alloca, or introduce a destructor). That will show whether the compiler kept storage in the prologue, used registers, or reused stack slots. For predictable debugger behavior, compile without optimizations; for best runtime code, trust the optimizer to elide or merge storage where safe.

Recommended Answers

All 3 Replies

Most/all C/C++ compilers have a swtich to allow you to view the assembled code

gcc's switch is -S

`-S'
Stop after the stage of compilation proper; do not assemble. The
output is in the form of an assembler code file for each
non-assembler input file specified.

Your compiler will have read the entire function, and worked out in advance just how much space each local variable would need (and the total space).

At code generation time, the right amount of stack space can be reserved.

Ok, I see. Thank you very much.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.