19

Why do books say, "the compiler allocates space for variables in memory". Isn't it the executable which does that? I mean, for example, if I write the following program,

#include <iostream>
using namespace std;

int main()
{
   int foo;
   return 0;
}

and compile it, and get an executable (let it be program.exe), now, if I run program.exe, this executable file will itself command to allocate some space for the variable foo. Won't it ? Please explain why books keep on saying, "the compiler will do this...do that".

8

8 Answers 8

20

You are right that the compiler as such is gone when your program actually runs. And if it runs on a different machine, the compiler isn't even available anymore.

I guess this is to make a clear distinction between memory actually allocated by your own code. The compiler will insert some code in your program that does the memory allocation (like using new, malloc or similar commands).

So books use "the compiler does this or that" often to say the compiler added some code that is not explicitly mentioned in your code files. True enough that this isn't exactly what's going on. From this point of view a lot of things mentioned in tutorials would be wrong but would need rather elaborate explanations.

4
  • Yes, that's what I believed. Thanks for a quick answer!
    – Shravan
    Apr 4, 2013 at 8:29
  • 12
    the compiler allocates for the variable foo on the stack by substituting it by an offset to the stack pointer during compilation. It is not at all related to heap allocation which is done by malloc et. al.
    – wirrbel
    Apr 4, 2013 at 9:18
  • @holger: You objection is technically correct of course. But the stack space as such must still be allocated when the program starts before it can be used (which may happen in various ways, sometimes depending on the CPU architecture). I tried to find some details how this happens but with not much success. Apr 6, 2013 at 12:11
  • 2
    I think stack size for the main thread is reserved by the linker and then handled by the OS. For custom threads it is more similar to heap allocation i.e. the caller can fix the size at runtime.
    – wirrbel
    Apr 6, 2013 at 12:24
4

It depends on the variable. The OS allocates heap, the program will allocate stack and the compiler will allocate space for globals/statics, i.e. they're built into the exe itself. If you allocate 1MB of global memory your exe size will increase by at least 1MB

5
  • 1
    That's not what this question is about.
    – Philipp
    Apr 4, 2013 at 16:37
  • 2
    actually it is closer to the question than the other answers listed here.
    – wirrbel
    Apr 4, 2013 at 21:31
  • @James Ah, this is not my experience. For instance int test[256][1024]; int main(){ test[0][0]=2; return 0; } This small program has 1MB allocated but only generates me a 1.4 Kb object file and an 8.4 Kb executable. It should use the correct amount of RAM, though. Apr 9, 2013 at 21:57
  • 1
    Shouldn't it only be the allocation commands stored for globals? If you have hardcoded all the values using the primitives like int or char, the size of the executable would definitely increase by more than the amount of variables added. Such as int a1=1,a2=2, ... all the way to... , a1048576=1048576; Only then you'd definitely get something bigger than 1mb i think. Apr 9, 2013 at 22:06
  • 2
    It's whatever puts data into the BSS section of the exe
    – James
    Apr 9, 2013 at 23:17
4

what the compiler will do is take your code and compile it into machine code. What you mention is a good example where a compiler only needs to translate.

For instance, when you write

int foo;

You can view that as 'I am telling the compiler to [in the output it generates] request that the computer reserve enough ram for an int that I can reference later The compiler will probably use a resource id or some mechanism to track foo in the machine code, you get to use foo in a text file instead of writing assembly! Hurray!

So you might also look at this as the compiler is writing a letter (or perhaps a novel/encyclopedia) to all targeted processors and devices. The letter is written in binary signals that (generally) may be translated to different processors by changing the target. Any 'letter' and/or combo can be sending all sorts of requests and/or data - like please allocate space for this variable that the programmer used.

3

Saying "the compiler allocates memory" may not be factually accurate in the literal sense, but it's a metaphor that's suggestive in the right way.

What really happens is that the compiler creates a program that allocates its own memory. Except that it isn't the program that allocates memory, but the OS.

So what really happens is that the compiler creates a program that describes its memory requirements and the OS takes that description and uses it to allocate memory. Except that the OS is a program, and programs don't actually do anything, they describe a computation that is performed by the CPU. Except that the CPU is really just a complicated electronic circuit, not an anthropomorphised little homonculus.

But it makes sense to think of programs and compilers and CPUs as little people who live inside a computer, not because they actually are, but because that's a metaphor that fits the human brain well.

Some metaphors work well for describing things on one level of abstraction, but don't work as well on another level. If you think on the level of the compiler, it makes sense to describe the act of generating code that will result in memory being allocated when the program that is being compiled is actually run as "allocating memory". It's close enough that when we're thinking about how a compiler works, we have the right idea, and it's not so long-winded that we forget what we were doing. If we try to use that metaphor on the level of the compiled program running, it's misleading in a weird sort of way, which is what you noticed.

0

It's compiler who decides where to store a variable - can be in stack or a free register. Whatever the storage decision made by compiler, the corresponding machine code to access that variable will be generated and cannot be changed in run time. In this sense, the compiler is in charge of allocating space for variables and the final program.exe is just blindly acting like a zombie in run time.

Now, don't confuse this with different dynamic memory management like malloc, new or may be your own memory management. Compilers are dealing with variable storage and access but it doesn't care what an actual value means in another framework/library. For example:

byte* pointer = (byte*)malloc(...);

In run time, malloc may return an arbitrary number but the compiler doesn't care, all it cares is where to store that number.

0

A more accurate phrasing would be:- "the compiler tells the loader to reserve space for the variables"

In a C-ish environment there will be three types of space for variables:-

  • a fixed block for static variables
  • A large block for "automatic" variables usually referred to as the "stack". Functions grab a chunk on entry and release it on return.
  • A large block called the "heap" which is where program managed memory is allocated from (using malloc() or similar memory management API.

On a modern OS heap memory will not actually be reserved but allocated as required.

0

Yes, you're right, in this case (declaring a variable in a function), the sentence of your book is probably incorrect: when you declare a variable in a function, it gets allocated on the stack upon entering the function. Anyway, a compiler should optimize the situation: if the function is non-recursive (main() is a good candidate for it), the it's OK to "allocate" it compile-time (on the BSS).

(If you are curious about where your variables reside, you can check it a dirty way (if you don't want to examine obj file structure, anyway, why not?), so you can declare some different kind of variables: constant, static, dynamic, malloc()-allocated etc., and display their addresses (use %X formatter in printf() for better readability). The variables reside on the stack will have very different memory addresses.)

0

The only thing done at runtime will be bumping the stack poinbter by a certain amount. So the compiler decides beforehand:

  • how much stack space will be needed for the function.
  • At what offset from the stack pointer every individual variable will be located.

This one can be called "allocation", but of course, during compile time it takles place only in the model the compiler has of the running program.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.