468,768 Members | 1,690 Online

# Local Variable Alignment

Hi,

I need to write a piece of code that will let me find the address boundaries of various local variables in order to determine their alignment. I was wondering if anyone would

a) Be able to explain to me exactly what the alignment of a local variable means (is it that it has something to do with its memory address being divizible by 4?)

b) Be able to give me a hint on how exactly I go about doing this (note in explaining a this will probably solve b too.)

cheers!
Apr 13 '07 #1
6 5805
JosAH
11,448 Expert 8TB
Hi,

I need to write a piece of code that will let me find the address boundaries of various local variables in order to determine their alignment. I was wondering if anyone would

a) Be able to explain to me exactly what the alignment of a local variable means (is it that it has something to do with its memory address being divizible by 4?)

b) Be able to give me a hint on how exactly I go about doing this (note in explaining a this will probably solve b too.)

cheers!
Local variables live on the stack. For most processors nowadays an int can
only be stored on a 4 byte boundary so a local variable of type int needs to
be stored at an address wich can be divided by 4. chars just have a one byte
boundary (on most processors) and doubles can have even more strict
allignment boundaries (8 for example). Local variables are no exception to that
rule so local variables may take up a bit more stack space than logically expected.

kind regards,

Jos
Apr 13 '07 #2
Ah cool, so would I be right in saying that in order to find out the alignment of say, a locally declaired variable of type int, I would divide the address at which it is stored by 4? if there is no remainder then it is stored on a 4 byte boundary? And thus with differing variable types such as char and double I would divide by 1 and 8 respectively to check their boundaries are 1 and 8 bytes?
Apr 13 '07 #3
83 Expert
in order to find out the alignment of say, a locally declaired variable of type int, I would divide the address at which it is stored by 4? if there is no remainder then it is stored on a 4 byte boundary?
To test if the address is divisible by 4, you can use modular division, like this:
if ((int)&var % 4 == 0) { ... }

Note, however, that from a logical standpoint, showing that a particular variable is 4-byte or 8-byte aligned does not prove that the compiler always does it that way. I think you could spend quite a bit of time trying to devise ways to demonstrate that the compiler is actually doing alignment. I think the best evidence you will find for alignment is the gaps of unused memory that it tends to create when you have variables of different sizes on the stack.

One interesting exercise would be to actually set the memory for the space containing all the variables in the stack frame to a particular value using memset, then explicitly set the value of each variable to a different value, then display the raw byte values of that memory space. I'll let you think about how you could do that, just ask if you want a clearer idea of how to go about it.

Keep in mind that variables are not necessarily allocated on the stack in the order that you declare them, as the compiler is free to reorder them in any way it sees fit.

Without actually setting values in memory, such a test could be simulated by creating an array of values, representing a "diagram" of the bytes in the current stack frame, and fill in the elements of the array corresponding to the bytes used by the variables on the stack.
Apr 13 '07 #4
To test if the address is divisible by 4, you can use modular division, like this:
if ((int)&var % 4 == 0) { ... }
I just tried this there, but I don't see how that can show if something can be 8 byte aligned if you change it to :

if ((int)&var % 8 == 0) { ... }

as seeing how 8 is also divisible by 4, it is more than likely that anything divisible by 4 will also be divisible by 8, and vice versa.

In order to find out alignment, could I just declare 2 variables of the same type, take one away from the other and then see if the difference is divisible by 4 or 8 for 4 and 8 byte alignment respectively (providing there is no padding)?

Note, however, that from a logical standpoint, showing that a particular variable is 4-byte or 8-byte aligned does not prove that the compiler always does it that way. I think you could spend quite a bit of time trying to devise ways to demonstrate that the compiler is actually doing alignment. I think the best evidence you will find for alignment is the gaps of unused memory that it tends to create when you have variables of different sizes on the stack.

One interesting exercise would be to actually set the memory for the space containing all the variables in the stack frame to a particular value using memset, then explicitly set the value of each variable to a different value, then display the raw byte values of that memory space. I'll let you think about how you could do that, just ask if you want a clearer idea of how to go about it.

Keep in mind that variables are not necessarily allocated on the stack in the order that you declare them, as the compiler is free to reorder them in any way it sees fit.

Without actually setting values in memory, such a test could be simulated by creating an array of values, representing a "diagram" of the bytes in the current stack frame, and fill in the elements of the array corresponding to the bytes used by the variables on the stack.
As to the rest of the post, it is really appreciated! However, :P, I have not been doing low level programming long enough, and am certainly not good enough, to get anymore than a rough idea of what you are talking about there. I understand what you are talking about with the memset etc, however I don't have nearly enough experience to be able to take the next step and actually put it in practice without a little more explaination. Sorry :( !
Apr 14 '07 #5
JosAH
11,448 Expert 8TB
You don't need actual objects to check the alignment. Have a look:
Expand|Select|Wrap|Line Numbers
1. typedef struct {
2.    char dummy;
3.    double d;
4. } dbl_t;
5. ...
6. cout << "double alignment: " << offsetof(dbl_t, d) << endl;
kind regards,

Jos

ps. btw, the numbers 4, 12, 20, 28 ... are all divisable by 4 but not by 8 ;-)
Apr 14 '07 #6
You don't need actual objects to check the alignment. Have a look:
Expand|Select|Wrap|Line Numbers
1. typedef struct {
2.    char dummy;
3.    double d;
4. } dbl_t;
5. ...
6. cout << "double alignment: " << offsetof(dbl_t, d) << endl;
kind regards,

Jos

ps. btw, the numbers 4, 12, 20, 28 ... are all divisable by 4 but not by 8 ;-)
Ah cheers! this is exactly what I was looking for, it makes sense now also :)

p.s. Can doubles have a 4 byte alignment sometimes, and at others an 8 byte alignment, cos this is giving me a 4 byte alignment and I remember in your first post something about doubles with 8 byte alignments?
Apr 14 '07 #7