1

I'm learning C++ from basics (using Visual Studio Community 2015)

While working on the arrays I came across the following:

int main()
{
    int i[10] = {};
}

The assembly code for this is :

    18:     int i[10] = {};
008519CE 33 C0                xor         eax,eax  
008519D0 89 45 D4             mov         dword ptr [ebp-2Ch],eax  
008519D3 89 45 D8             mov         dword ptr [ebp-28h],eax  
008519D6 89 45 DC             mov         dword ptr [ebp-24h],eax  
008519D9 89 45 E0             mov         dword ptr [ebp-20h],eax  
008519DC 89 45 E4             mov         dword ptr [ebp-1Ch],eax  
008519DF 89 45 E8             mov         dword ptr [ebp-18h],eax  
008519E2 89 45 EC             mov         dword ptr [ebp-14h],eax  
008519E5 89 45 F0             mov         dword ptr [ebp-10h],eax  
008519E8 89 45 F4             mov         dword ptr [ebp-0Ch],eax  
008519EB 89 45 F8             mov         dword ptr [ebp-8],eax  

Here, since initalisation is used every int here is initialised to 0 (xor eax,eax). This is clear.

From what I have learnt, any variable would be allocated memory only if it is used (atleast in modern compilers) and if any one element in an array is initialised the complete array would be allocated memory as follows:

int main()
{
    int i[10];
    i[0] = 20;
    int j = 20;
}

Assembly generated:

    18:     int i[10];
    19:     i[0] = 20;
00A319CE B8 04 00 00 00       mov         eax,4  
00A319D3 6B C8 00             imul        ecx,eax,0  
00A319D6 C7 44 0D D4 14 00 00 00 mov         dword ptr [ebp+ecx-2Ch],14h  
    20:     int j = 20;
00A319DE C7 45 C8 14 00 00 00 mov         dword ptr [ebp-38h],14h  

Here, the compiler used 4 bytes (to copy the value 20 to i[0]) but from what I have learnt the memory for the entire array should be allocated at line 19. But the compiler haven't produced any relevant machine code for this. And where would it store info (stating that the remaining memory for the other nine elements[1-9] of array i's cannot be used by other variables)

Please help!!!

infinite loop
  • 1,309
  • 9
  • 19
  • there's a difference between allocation and initialisation. Because you didn't offer a brace-initialisation for `i` in the second example, all elements are of undefined value. – Richard Hodges Jun 05 '17 at 13:10
  • 1
    *"From what I have learnt, any variable would be allocated memory only if it is used (atleast in modern compilers)"* This generally only holds for optimized code (more as a rule of thumb, compiler optimizations are hard for predict), under which your code compiles to `int main(){}` because it does nothing. *"if any one element in an array is initialised the complete array would be allocated memory"* There is no such rule. – Baum mit Augen Jun 05 '17 at 13:11
  • I would highly suggest starting with a book from the [C++FAQ](https://stackoverflow.com/q/388242/332733) instead of learning C – Mgetz Jun 05 '17 at 13:11
  • 1
    If you're getting an `imul` instruction that multiplies by 0 (!), then you are obviously looking at unoptimized code. Don't waste your time with that. If you want to study how C++ gets translated to machine code, then you want to enable the optimizer (`/O2` in Visual C++). – Cody Gray - on strike Jun 05 '17 at 13:12
  • @CodyGray `/O2` is going to eliminate the entire program. – Richard Hodges Jun 05 '17 at 13:16
  • So if any new variable is allocated, how it knows that it has to allocated it out of that bound (memory space for 1 - 9 elements). Will the compiler calculate that before generating the machine code for allocating remaining variables? Please correct me if I'm wrong anywhere. I'm just a beginner trying to learn Cpp. – infinite loop Jun 05 '17 at 13:17
  • 1
    That's correct, @Richard, and that will give him a better idea of how memory allocation works. In this case, it doesn't, because the objects are not actually used anywhere. This is all static allocation, and is trivially optimizable at compile-time. – Cody Gray - on strike Jun 05 '17 at 13:18
  • @CodyGray, the above assembly has been generated with `/02` optimization but in debug mode. Have changed it to release mode and yeah as @RichardHoges said it elimated the code. I'm really suprised with the level of optimisation it does in `/02` in release mode. Its allocating only at the point I'm actually using the variable. So, should I learn the machine code of C++, I should learn optimised code? – infinite loop Jun 05 '17 at 14:31
  • N please answer my b4 comment "So if any new variable is allocated, how it knows that it has to allocated it out of that bound (memory space for 1 - 9 elements). Will the compiler calculate that before generating the machine code for allocating remaining variables?" – infinite loop Jun 05 '17 at 14:32
  • @BaummitAugen, "if any one element in an array is initialised the complete array would be allocated memory" ***There is no such rule.*** Consider, if the array element is actually used (printing or passing array to a func), then the storage for the complete array will be created? Am I correct? – infinite loop Jun 05 '17 at 15:04
  • 1
    @infiniteloop Maybe, maybe not. The compiler can do all sorts of changes to your code, including eliminating variables and entire functions, as long as the observable behavior stays the same. (Runtime and memory allocation do not count here, the abstract machine need not have finite speed or memory.) – Baum mit Augen Jun 05 '17 at 15:07
  • 1
    There is no such thing as /O2 optimization in debug mode. Debug mode is /Od, which means optimizations disabled. /O2 means optimize for speed. The two modes are mutually exclusive. What you should do is learn C++, and you should do that by reading a book that teaches you C++. Then, once you already know C++, you can start peeking under the hood to see what a good optimizing compiler can do with your C++ code to make it maximally efficient. Like you see here, it eliminates all the variables—since you never actually use them, they don't need to take up any space or time. – Cody Gray - on strike Jun 05 '17 at 16:12

0 Answers0