Local Variable Alignment

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • Facultas
    New Member
    • Apr 2007
    • 9

    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!
  • JosAH
    Recognized Expert MVP
    • Mar 2007
    • 11453

    #2
    Originally posted by Facultas
    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

    Comment

    • Facultas
      New Member
      • Apr 2007
      • 9

      #3
      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?

      Comment

      • nmadct
        Recognized Expert New Member
        • Jan 2007
        • 83

        #4
        Originally posted by Facultas
        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.

        Comment

        • Facultas
          New Member
          • Apr 2007
          • 9

          #5
          Originally posted by nmadct
          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)?

          Originally posted by nmadct
          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 :( !

          Comment

          • JosAH
            Recognized Expert MVP
            • Mar 2007
            • 11453

            #6
            You don't need actual objects to check the alignment. Have a look:
            Code:
            typedef struct {
               char dummy;
               double d;
            } dbl_t;
            ...
            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 ;-)

            Comment

            • Facultas
              New Member
              • Apr 2007
              • 9

              #7
              Originally posted by JosAH
              You don't need actual objects to check the alignment. Have a look:
              Code:
              typedef struct {
                 char dummy;
                 double d;
              } dbl_t;
              ...
              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?

              Comment

              Working...