1

How does the c++ compiler organize the variables that are initialized in a function to store them so the computer will find them the fastest way?

I understand that the compiler puts them one after an other on the stack but there has to be some logic behind it, I was searching Google for hours on end but I could not find anything.

For example:

int main()
{
    float a;
    int b;
    char c;
    double d;
}

This should occupy more memory than the one below because of the way the c++ compiler is storing in the memory.

The exact bits used are the same, of course, but they should be stored in a more efficient order in the example below. Where in memory would these variables be stored by the compiler in the next example? As far as I understood a variable is always stored on a block such that (logical number) % (number of bytes the datatype) = 0

int main()
{
    char c;
    int b;
    float a;
    double d;
}
drescherjm
  • 10,365
  • 5
  • 44
  • 64
MSlayer
  • 13
  • 1
  • 3
  • `stack` is not the only way to realize automatic variables – user2736738 Jan 06 '17 at 15:13
  • @coderredoc: The C++ standard requires stack behavior for automatic local variables, so it is the only way. How that stack is implemented is not prescribed. – Cheers and hth. - Alf Jan 06 '17 at 15:17
  • 1
    @MSlayer: The order of namespace scope variables in each translation unit is defined. The order of data items with the same access level, in a given class instance, is defined. The order of local automatic variables (in memory), is not defined. The implementation is free to move these around. However, it must ensure that constructors are called in the order of declaration of the variables, and opposite for destructors. – Cheers and hth. - Alf Jan 06 '17 at 15:19
  • @Cheersandhth.-Alf.: Yes that's true...stack ADT and it's implementation...is different. – user2736738 Jan 06 '17 at 15:24
  • 1
    In both examples all the variables will be optimized away since they are unused. Both examples will in most (probably all) compilers give the same binary as `int main() { }`. – PeterSW Jan 06 '17 at 15:26
  • 2
    On modern systems the stack pointer also has some alignment requirements. So if you remove padding between the variables, you might instead get the same padding bytes added after the variables. You are never going to have the stack pointer moved exactly 17 bytes for these variables. – Bo Persson Jan 06 '17 at 15:39

4 Answers4

3

There is no requirement in the C++ standard for automatic (what you called stack) variables to be laid out in a certain order or location (as long as alignment requirements are satisfied).

Maxim Egorushkin
  • 131,725
  • 17
  • 180
  • 271
0

This should occupy more memory than the one below because of the way the c++ compiler is storing in the memory.

Not really, the stack memory consumed by both functions should be the same for any sane optimizing compiler... Modern C++ Compilers are really aggressive at certain optimizations.

Other than suitable alignments, C++ does not impose memory address ordering for automatic variables in functions. While that is true, the observable behavior of the program must not be changed by the compiler.

I guess you are trying to talk about structs and classes where the memory layout and address ordering of variables are as declared.

How does the c++ compiler organize the variables that are initialized in a function to store them so the computer will find them the fastest way?

In practice, every access to an automatic variable in C++ is a simple pointer offset with respect to the stack pointer1 (except variables the compiler placed directly in a register). Additionally, to speed things up to such automatic variables (in no order):

  • The Compiler eliminates dead variables

  • The compiler will find the best order to store each of them to meet suitable alignment

  • The compiler may use the CPU register directly depending on what it's Register Allocation algorithm decides

  • The compiler may lump certain variables together into a vector register and use vector instructions provided it will yield correct results.

  • ...and so much more.


1: Even the stack pointer is aligned by most compilers.

Community
  • 1
  • 1
WhiZTiM
  • 21,207
  • 4
  • 43
  • 68
  • Also important: automatic variables may share the same address, if they have trivial destructors and effectively non-overlapping lifetimes, and addresses may change (!) while running. – MSalters Jan 06 '17 at 18:04
0

Registers and optimizations.
The most efficient access of variables is to eliminate them. Many compilers will optimize away variables that are not used.

If a variable is used locally, the compiler may decide to place the variable in a register. Registers are the most efficient access for variables.

A stack is a convenient data structure for allocating local variables. The compiler can destroy variables on the stack by changing the stack pointer. Implementations that use a stack often have a pointer to the top of the stack (where the next variable is allocated). Allocation is as simple as adjusting the pointer by a constant (which is an arithmetic operation).

Remember, there is no requirement that a compiler use a stack.

Thomas Matthews
  • 56,849
  • 17
  • 98
  • 154
0

Thank you for helping, I now also foud a not too bad description of the logic I was looking for, for anyone who is interressted I will post the link here: http://www.tenouk.com/Bufferoverflowc/Bufferoverflow2.html http://www.tenouk.com/Bufferoverflowc/Bufferoverflow2a.html

MSlayer
  • 13
  • 1
  • 3