1

I`m curious about such C code:

void test(int y){
   if (y) {
      int x = 1;
      printf("Test: %d", x + y);
   }
   // other important code (don`t use x var)
}

Necessity of x variable depends on y. For instance: if we call test(0), we don't need to allocate space for x variable, for test(1) invocation x variable must exist in memory.

Does this kind of technique used by modern compilers?

kirugan
  • 2,514
  • 2
  • 22
  • 41

3 Answers3

2

A more likely optimization by the compiler is

void test(int y){
   if (y) {
      printf("Test: %d", 1 + y);
   }
   // other important code (don`t use x var)
}

and then we don't need x in either case.

Bo Persson
  • 90,663
  • 31
  • 146
  • 203
1

As Sourav Ghosh says, "Nothing you can be certain of!", however, let me give some possibilities a compiler might use.

First, syntactically speaking, a variable in a block only is known within the block. Outside the block the compiler (language) has forgotten all about it. So you can use this block construct to have a temporary variable.

What can the compiler do?

Probably a compiler will calculate the maximum storage of all blocks (that is, the automatic variables declared upon function entry (function scope) plus the size of the largest block, plus the size of the largest nested block,... etc.) and allocate that amount on the stack. When a block is exited, the compiler knows its variables do not exist anymore and can re-use that space (on the stack) for any following block. In Fortran this is called an overlay and it is comparible to a union in C.

Equally posible, a compiler might allocate new space on the stack (e.g. sub sp, 12) upon entering a block, and release it upon leaving the block (e.g. add sp, 12).

And there may be other strategies that I don't know of.

Paul Ogilvie
  • 25,048
  • 4
  • 23
  • 41
  • Also, an auto variable might not stay in the same place in the stack frame throughout the execution of the function. If the value of a variable changes, the compiler might decide to keep the value somewhere else and use the old storage location for something else. It only really needs to pin it down while something is pointing to it. – Ian Abbott Nov 11 '15 at 17:53
  • @Sourav-Ghosh, oops...sorry, corrected the spelling. – Paul Ogilvie Nov 12 '15 at 12:15
0

What the compiler does will vary based on optimization level but one would expect at the highest optimization level a modern compiler would do everything in registers with x being constant folded away since it is a constant 1 and we can see from this godbolt session gcc does just that:

test:
    testl   %edi, %edi
    jne .L4
    rep ret
.L4:
    leal    1(%rdi), %esi
    xorl    %eax, %eax
    movl    $.LC0, %edi
    jmp printf

at the lowest optimization level we don't expect anything clever and in this case gcc allocates for both x and y without checking if x is actually required:

subq    $32, %rsp
Shafik Yaghmour
  • 154,301
  • 39
  • 440
  • 740