Reputation: 416
int main(){
int p = 10 , q = 11;
int a[3];
int * ptr = &q;
cout << *ptr+1 <<endl;
cout <<"P = " << (int)&p <<endl;
cout <<"q = " << (int)&q <<endl;
cout << "Size of p = "<< sizeof(p) <<endl;
cout << "(int)&a[0]:" << (int)&a[0] <<endl;
cout << "(int)&a[1]:" << (int)&a[1] <<endl;
cout << "(int)&a[2]:" << (int)&a[2] <<endl;
}
And the output of this code is
12
P = 14679472
q = 14679460
Size of p = 4
(int)&a[0]:14679440
(int)&a[1]:14679444
(int)&a[2]:14679448
Now i have few questions .
- int take 4 bytes or 8 bytes but here the difference between p and q is 12. I don't get it ? what it is? am i missing something important here ?
- I was actually reading about about stack frame so any body can explain or provide a good study material what it is would be really appreciated.
Upvotes: 2
Views: 126
Reputation: 881363
With regard to (paraphrased):
An
int
take four or eight bytes but here the difference betweenp
andq
is twelve.
An int
does not take four or eight bytes, that's just a common thing in many implementations. The standard specifies a minimum range but no maximum. In any case, the standard does not mandate that distinct variables are allocated on the stack in any particular order. In fact, it doesn't mandate a stack at all, it just has to behave in a certain way.
Granted arrays have to be ordered in a certain way (as you can see from the addresses of the a
elements) but p
and q
are not part of an array. And, even thought the a
element addresses are four bytes apart, even that is not mandated. An implementation is free to add padding between elements and after the last element.
Since you can't (safely) use the address of p
to do anything other than access p
itself, it's address is actually irrelevant.
In regard to your second question about good reference material, that's actually disfavoured by Stack Overflow, one of the close reasons being:
Seeking recommendations for books, tools, software libraries, and more. This question is likely to lead to opinion-based answers.
Hence I won't bother answering that bit.
However, I will give a bit of extra advice: if you really want to know what specific implementations are doing with your code, you should head on over to GodBolt and type your code in. Making some minor modifications to get it to compile cleanly:
#include <iostream>
#define USE_P 1
#define USE_Q 1
#define USE_A 1
int main() {
#if USE_P
int p = 10;
#endif
#if USE_Q
int q = 11;
#endif
#if USE_A
int a[3] = {12, 13, 14};
#endif
std::cout << "hello\n";
}
You'll see something at the start of main
that looks like this (though I added the comments):
push rbp
mov rbp, rsp
sub rsp, 32 // Stack frame size
mov DWORD PTR [rbp-4], 10 // p
mov DWORD PTR [rbp-8], 11 // q
mov DWORD PTR [rbp-20], 12 // a[0]
mov DWORD PTR [rbp-16], 13 // a[1]
mov DWORD PTR [rbp-12], 14 // a[2]
And you watch how this changes when you tell it to stop using any of those variables, in any combination. From the example I gave (and using x86-64 gcc 10.1
), it appears that the variables are placed as you expected. However, as stated earlier, this is not a requirement.
Upvotes: 2
Reputation: 10430
Why it is priniting 12 for *ptr+1
As per operator precedence, deference operator *
will be executed first and it will give the value of 11
. 11
plus 1
is 12
.
int take 4 bytes or 8 bytes but here the difference between p and q is 12. I don't get it ? what it is? am i missing something important here ?
The compiler/implementation can save the variable with auto storage class in any order. Even, in some implementation, there couldn't a stack at all. The standard just defines the behavior and each implementation has to abide to it but they are free to use any data structure for function calls (but I think stack are mostly used). There could be some variables in between p
and q
with as much padding as it wants.
I was actually reading about about stack frame so any body can explain or provide a good study material what it is would be really appreciated.
Upvotes: 1