Eight-byte alignment

Discussion in 'C++' started by glchin@hotmail.com, Dec 3, 2007.

  1. Guest

    Does a compiler guarantee that the variable w below is placed on an
    eight-byte aligned address?


    void myFunction( long iFreq )
    {
    const double w = two_pi * iFreq;
    ...
    ...
    }
    , Dec 3, 2007
    #1
    1. Advertising

  2. wrote:
    > Does a compiler guarantee that the variable w below is placed on an
    > eight-byte aligned address?


    No. There are no requirement in C++ Standard WRT specific alignment
    for any objects.

    You will find that every compiler/platform is different in that sense
    and that many compilers (if not all) have a way for you to control the
    alignment boundary.

    > void myFunction( long iFreq )
    > {
    > const double w = two_pi * iFreq;
    > ...
    > ...
    > }


    V
    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask
    Victor Bazarov, Dec 3, 2007
    #2
    1. Advertising

  3. Re: This code, similar to yours, GLChin:
    “ main() { const double w = 0 ; } â€,

    The address of “ w †is 8-byte-aligned.
    Using VC++ 8, you can check for yourself, like this:

    #pragma warning( disable: 4007 4189 4430 4508 )
    WinMain( int, int, int, int ) {
    const __int32 Int32 = 0 ; const __int64 Int64 = 0 ;

    int Implicit_Size_of_Int32 = int( & Int64 ) - int( & Int32 );
    // Breaking here, “ Implicit_Size_of_Int32 == 8 â€.
    }
    Jeff☠Relf, Dec 3, 2007
    #3
  4. <> wrote in message
    news:...
    > Does a compiler guarantee that the variable w below is placed on an
    > eight-byte aligned address?
    >
    >
    > void myFunction( long iFreq )
    > {
    > const double w = two_pi * iFreq;
    > ...
    > ...
    > }


    Yes, the compiler always guarantees that variables are by default aligned
    correctly for their type. Since this is a double, it will be 8-byte
    aligned. Since this is a const double, there's no requirement that the
    compiler allocate any memory for it at all - it could be enregistered or
    re-calculated wherever used. In practice, the compiler probably assigns
    memory for it, which would be 8-byte aligned.

    The only time memory won't be aligned is when you've used #pragma pack, one
    of the memory alignment command-line options, or done pointer arithmetic
    yourself that doesn't honor the type's alignment.

    -cd
    Carl Daniel [VC++ MVP], Dec 3, 2007
    #4
  5. I'm not sure that in 32-bit environment there is a stack frame alignment
    guarantee, other than 4 bytes, of course. Thus, any doubles might be
    unaligned.

    "Carl Daniel [VC++ MVP]" <>
    wrote in message news:...
    > <> wrote in message
    > news:...
    >> Does a compiler guarantee that the variable w below is placed on an
    >> eight-byte aligned address?
    >>
    >>
    >> void myFunction( long iFreq )
    >> {
    >> const double w = two_pi * iFreq;
    >> ...
    >> ...
    >> }

    >
    > Yes, the compiler always guarantees that variables are by default aligned
    > correctly for their type. Since this is a double, it will be 8-byte
    > aligned. Since this is a const double, there's no requirement that the
    > compiler allocate any memory for it at all - it could be enregistered or
    > re-calculated wherever used. In practice, the compiler probably assigns
    > memory for it, which would be 8-byte aligned.
    >
    > The only time memory won't be aligned is when you've used #pragma pack,
    > one of the memory alignment command-line options, or done pointer
    > arithmetic yourself that doesn't honor the type's alignment.
    >
    > -cd
    >
    >
    Alexander Grigoriev, Dec 4, 2007
    #5
  6. James Kanze Guest

    On Dec 3, 6:22 pm, wrote:
    > Does a compiler guarantee that the variable w below is
    > placed on an eight-byte aligned address?


    > void myFunction( long iFreq )
    > {
    > const double w = two_pi * iFreq;
    > ...
    > ...
    > }


    A compiler does, but I don't know if your using that compiler.
    Certainly not all compilers do---it wouldn't make sense on a
    machine where sizeof(double) is 6, for example, nor on a 16 bit
    machine. Depending on the hardware, it might not even make
    sense on a 32 bit machine (nor a 36 bit machine, for that
    matter).

    The real question is why do you care? The compiler will
    guarantee that w meets whatever requirements the hardware makes
    for effective access. And that's really all you care about.

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
    James Kanze, Dec 4, 2007
    #6
  7. James Kanze Guest

    On Dec 3, 7:43 pm, "Carl Daniel [VC++ MVP]"
    <> wrote:
    > <> wrote in message


    > news:...


    > > Does a compiler guarantee that the variable w below is
    > > placed on an eight-byte aligned address?


    > > void myFunction( long iFreq )
    > > {
    > > const double w = two_pi * iFreq;
    > > ...
    > > ...
    > > }


    > Yes, the compiler always guarantees that variables are by
    > default aligned correctly for their type.


    Which on most 32 bit machines is any multiple of 4. On the one
    48 bit machine I'm aware of, it would be a multiple of 6. On
    the various 36 bit machines I've seen or heard of, it would be a
    multiple of 4 as well. On the earlier 16 bit machines I
    worked on, it would be multiple of 2, and on the 8 bit machines,
    there were no alignment restrictions.

    > Since this is a double, it will be 8-byte aligned.


    On a Sun Sparc, probably. On an Intel based 32 bit machine, I
    doubt it, and on the older, 16 bit Intels, almost certainly not.

    > Since this is a const double, there's no requirement that the
    > compiler allocate any memory for it at all - it could be
    > enregistered or re-calculated wherever used. In practice, the
    > compiler probably assigns memory for it, which would be 8-byte
    > aligned.


    > The only time memory won't be aligned is when you've used
    > #pragma pack,


    Which is implementation defined. Maybe it starts a game of
    packman.

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
    James Kanze, Dec 4, 2007
    #7
  8. James Kanze Guest

    On Dec 3, 7:07 pm, Jeff?Relf <> wrote:
    > Re: This code, similar to yours, GLChin:
    > ? main() { const double w = 0 ; } ?,


    > The address of ? w ? is 8-byte-aligned.
    > Using VC++ 8, you can check for yourself,


    You can check whether it is 8 byte aligned in one particular
    case, after whatever calls preceded it.

    > like this:


    > #pragma warning( disable: 4007 4189 4430 4508 )
    > WinMain( int, int, int, int ) {
    > const __int32 Int32 = 0 ; const __int64 Int64 = 0 ;


    > int Implicit_Size_of_Int32 = int( & Int64 ) - int( & Int32 );
    > // Breaking here, ? Implicit_Size_of_Int32 == 8 ?.
    > }


    I'm not sure what that's supposed to check. It's not C++, so it
    doesn't tell us anything about what C++ does. And I don't see
    how it would be related to how VC++ would lay out a double.

    FWIW: VC++ doesn't guarantee 8 byte alignment. All of my
    compilers on Sparc do---perhaps because accessing a double at an
    address which isn't 8 byte aligned will cause a core dump:).
    Curiously, g++ on both the Linux machine and the Windows
    machines here (32 bit Intel) also seems to guarantee 8 byte
    alignment.

    You might try something like the following:


    #include <iostream>

    double two_pi = 6.28 ;

    void
    f( long ifreq )
    {
    double w = two_pi * ifreq ;
    std::cout << &w << std::endl ;
    }

    void
    g()
    {
    f( 20 ) ;
    }

    template< size_t N >
    void
    h()
    {
    char dummy[ N ] ;
    f( 20 ) ;
    }

    template< size_t N >
    void
    i()
    {
    char dummy[ N ] ;
    double w ;
    std::cout << &w << std::endl ;
    }

    int
    main()
    {
    f( 20 ) ;
    g() ;
    h< 1 >() ;
    h< 2 >() ;
    h< 3 >() ;
    h< 4 >() ;
    h< 5 >() ;
    h< 6 >() ;
    h< 7 >() ;
    h< 8 >() ;
    i< 1 >() ;
    i< 2 >() ;
    i< 3 >() ;
    i< 4 >() ;
    i< 5 >() ;
    i< 6 >() ;
    i< 7 >() ;
    i< 8 >() ;
    return 0 ;
    }

    If all of the addresses output are multiples of 8, it still
    isn't guaranteed, but I'd guess that there is a very good chance
    of it being true. If they aren't, of course, you know that it
    isn't guaranteed.

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
    James Kanze, Dec 4, 2007
    #8
  9. “ VC++ 8.0 †8-byte-aligns a “ __int64 â€, same as a “ double â€.

    “ VC++ 8.0 †8-byte-aligns a “ __int64 â€, same as a “ double â€.

    The code I showed ( news: )
    is most definately VC++ 8.0,
    complied and debuged using Visual Studio 2005.

    Had you tried it yourself, Mr. Kanze, you'd know that;
    but, naturally, you couldn't do that.
    Jeff☠Relf, Dec 4, 2007
    #9
  10. Re: " VC++ 8.0 " 8-byte-aligns a " __int64 ", same as a " double ".

    "Jeff?Relf" <> wrote in message
    news:...
    >" VC++ 8.0 " 8-byte-aligns a " __int64 ", same as a " double ".
    >
    > The code I showed ( news: )
    > is most definately VC++ 8.0,
    > complied and debuged using Visual Studio 2005.
    >
    > Had you tried it yourself, Mr. Kanze, you'd know that;
    > but, naturally, you couldn't do that.
    >


    Jeff, your code shows nothing at all, because it is in the main function.
    Stack alignment is dependent on the caller to some degree, if the caller
    left the stack 4-byte aligned, then you would not have 8-byte alignment.
    Ben Voigt [C++ MVP], Dec 4, 2007
    #10
  11. Re: " VC++ 8.0 " 8-byte-aligns a " __int64 ", same as a " double ".

    "Jeff?Relf" <> wrote in message
    news:...
    >" VC++ 8.0 " 8-byte-aligns a " __int64 ", same as a " double ".
    >
    > The code I showed ( news: )
    > is most definately VC++ 8.0,
    > complied and debuged using Visual Studio 2005.
    >
    > Had you tried it yourself, Mr. Kanze, you'd know that;
    > but, naturally, you couldn't do that.


    Furthermore, your code demonstrates packing, not alignment.
    Ben Voigt [C++ MVP], Dec 4, 2007
    #11
  12. Ben, how do you explain “ Implicit_Size_of_Int32 == 8 †?

    Re: This code of mine:
    “ #pragma warning( disable: 4007 4189 4430 4508 )
    WinMain( int, int, int, int ) {
    const __int32 Int32 = 0 ; const __int64 Int64 = 0 ;

    int Implicit_Size_of_Int32 = int( & Int64 ) - int( & Int32 );
    // Breaking here, “ Implicit_Size_of_Int32 == 8 â€.
    } â€.

    How do you ( Ben ) explain “ Implicit_Size_of_Int32 == 8 â€
    if it's not a manifestation of 8-byte alignment ?

    Remove the “ const †terms, or change them to “ static â€,
    and you still get the same results.
    Jeff☠Relf, Dec 4, 2007
    #12
  13. James Kanze Guest

    Re: " VC++ 8.0 " 8-byte-aligns a " int64 ", same as a " double ".

    On Dec 4, 11:52 pm, Jeff?Relf <> wrote:
    > ? VC++ 8.0 ? 8-byte-aligns a ? __int64 ?, same as a ? double ?.


    > The code I showed (news:)
    > is most definately VC++ 8.0,
    > complied and debuged using Visual Studio 2005.


    > Had you tried it yourself, Mr. Kanze, you'd know that;
    > but, naturally, you couldn't do that.


    No I couldn't, because VC++ doesn't work on my machine (a Sun
    Sparc). It's certainly not C++, and if you tried it with any
    even halfway conformant compiler (e.g. g++ -std=c++98, or even
    VC++, with the proper options), you'd know that.

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
    James Kanze, Dec 5, 2007
    #13
  14. schrieb:

    > Does a compiler guarantee that the variable w below is placed on an
    > eight-byte aligned address?
    >
    > void myFunction( long iFreq )
    > {
    > const double w = two_pi * iFreq;
    > ...
    > ...
    > }


    Some compilers do, some compilers don't.
    Visual Studio 2005 does align that way, as long as you do not modify the
    default alignment.

    Have a look in the online help for "__alignof" and
    "__declspec(align(n))" to find more information:
    http://msdn2.microsoft.com/en-us/library/45t0s5f4(VS.80).aspx
    http://msdn2.microsoft.com/en-us/library/83ythb65(VS.80).aspx

    There is no portable way to guarantee a particular alignment. If you
    really think you need one, you have to check the technical manuals of
    all compilers that you need to support.

    Norbert
    Norbert Unterberg, Dec 5, 2007
    #14
  15. Re: Ben, how do you explain " Implicit_Size_of_Int32 == 8 " ?

    "Jeff?Relf" <> wrote in message
    news:...
    > Re: This code of mine:
    > " #pragma warning( disable: 4007 4189 4430 4508 )
    > WinMain( int, int, int, int ) {
    > const __int32 Int32 = 0 ; const __int64 Int64 = 0 ;
    >
    > int Implicit_Size_of_Int32 = int( & Int64 ) - int( & Int32 );
    > // Breaking here, " Implicit_Size_of_Int32 == 8 ".
    > } ".
    >
    > How do you ( Ben ) explain " Implicit_Size_of_Int32 == 8 "
    > if it's not a manifestation of 8-byte alignment ?


    It isn't alignment, it is padding.

    There's no requirement that the compiler put the variables in the order you
    specify, either.

    Stack alignment has to do with absolute addresses, not relative addresses.

    If the compiler put Int32 at address 1, and Int64 at address 9, your code
    would still print 8, but they would not be 8 byte aligned.

    The alignment of local variables is at the mercy of ESP when the function
    starts, which depends on the call stack. On x32, ESP only needs to be 4
    byte aligned.

    >
    > Remove the " const " terms, or change them to " static ",
    > and you still get the same results.
    >
    Ben Voigt [C++ MVP], Dec 5, 2007
    #15
  16. Re: Ben, how do you explain " Implicit_Size_of_Int32 == 8 " ?

    â“‹_Ben_Voigt_C, _D71eGS.Airband.NET Phx.GBL
    2.48 Hours, Outlook_O19, Dec 5, 2007, 11._1 A, BS99eu

    Re: This VC++ 8 code of mine, without the “ /O2 †compiler option:
    “ #pragma warning( disable: 4007 4189 4430 4508 )
    WinMain( int, int, int, int ) {
    const __int32 Int32 = 0 ; const __int64 Int64 = 0 ;

    int Implicit_Size_of_Int32 = int( & Int64 ) - int( & Int32 );
    // Breaking here, ‘ Implicit_Size_of_Int32 == 8 ’.
    } â€.

    Implicit_Size_of_Int32 is 8 --> because <-- VC++ aligned Int64.
    Yes, that created some padding, but that's not the issue.

    As I recently said in “ news: â€,
    the “ /O2 †compiler option f u c k s things up.
    Jeff☠Relf, Dec 5, 2007
    #16
  17. Re: Ben, how do you explain " Implicit_Size_of_Int32 == 8 " ?

    "Jeff?Relf" <> wrote in message
    news:...
    > ?_Ben_Voigt_C, _D71eGS.Airband.NET Phx.GBL
    > 2.48 Hours, Outlook_O19, Dec 5, 2007, 11._1 A, BS99eu
    >
    > Re: This VC++ 8 code of mine, without the " /O2 " compiler option:
    > " #pragma warning( disable: 4007 4189 4430 4508 )
    > WinMain( int, int, int, int ) {
    > const __int32 Int32 = 0 ; const __int64 Int64 = 0 ;
    >
    > int Implicit_Size_of_Int32 = int( & Int64 ) - int( & Int32 );
    > // Breaking here, ' Implicit_Size_of_Int32 == 8 '.
    > } ".
    >
    > Implicit_Size_of_Int32 is 8 --> because <-- VC++ aligned Int64.
    > Yes, that created some padding, but that's not the issue.


    Alignment creates padding, but padding does not create alignment.

    By measuring padding, you have not measured alignment. Really.

    >
    > As I recently said in " news: ",
    > the " /O2 " compiler option f u c k s things up.
    >


    You mean it shows that your assertion that the VC++ compiler always aligns
    to 8 byte boundaries is wrong.
    Ben Voigt [C++ MVP], Dec 5, 2007
    #17
  18. Ben Voigt [C++ MVP], Dec 5, 2007
    #18
  19. Show me the mis-alignment.

    Given VC++ 8.0 without so-called “ optimizations †or packing rules,
    You can't show me a __int64 static, local or const
    that isn't aligned on an 8-byte-boundry. I rest my case.
    Jeff☠Relf, Dec 6, 2007
    #19
  20. James Kanze Guest

    Re: Show me the mis-alignment.

    On Dec 6, 4:13 am, Jeff?Relf <> wrote:
    > Given VC++ 8.0 without so-called ? optimizations ? or packing rules,
    > You can't show me a __int64 static, local or const
    > that isn't aligned on an 8-byte-boundry. I rest my case.


    aligne.cc:

    #include <iostream>

    double two_pi = 6.28 ;

    void
    f( long ifreq )
    {
    __int64 w = two_pi * ifreq ;
    std::cout << &w << std::endl ;
    }

    void
    g()
    {
    f( 20 ) ;
    }

    template< size_t N >
    void
    h()
    {
    char dummy[ N ] ;
    f( 20 ) ;
    }

    template< size_t N >
    void
    i()
    {
    char dummy[ N ] ;
    __int64 w ;
    std::cout << &w << std::endl ;
    }

    int
    main()
    {
    f( 20 ) ;
    g() ;
    h< 1 >() ;
    h< 2 >() ;
    h< 3 >() ;
    h< 4 >() ;
    h< 5 >() ;
    h< 6 >() ;
    h< 7 >() ;
    h< 8 >() ;
    i< 1 >() ;
    i< 2 >() ;
    i< 3 >() ;
    i< 4 >() ;
    i< 5 >() ;
    i< 6 >() ;
    i< 7 >() ;
    i< 8 >() ;
    return 0 ;
    }

    Compiled with:
    cl /vmg /GR /Gy /EHs /J /nologo /D_CRT_SECURE_NO_DEPRECATE /MTd /
    GS- /Zi /w /D_DEBUG align.cc

    Output:
    0012FF40
    0012FF38
    0012FF34
    0012FF34
    0012FF34
    0012FF34
    0012FF30
    0012FF30
    0012FF30
    0012FF30
    0012FF44
    0012FF44
    0012FF44
    0012FF44
    0012FF44
    0012FF44
    0012FF44
    0012FF44

    Note that the original question concerned double, and this is
    just a quick edit of the program which I used to verify that
    VC++ doesn't guarantee alignment of double. I don't know why
    the discussion changed type---double is C++, __int64 isn't, and
    VC++ is the only compiler at my disposition which will compile
    the above. The fact remains that VC++ doesn't guarantee
    alignment of more than 4, ever.

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
    James Kanze, Dec 6, 2007
    #20
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. cfanatic
    Replies:
    3
    Views:
    545
    cfanatic
    Oct 16, 2003
  2. jblazi

    The eight queens problem

    jblazi, Aug 30, 2004, in forum: C++
    Replies:
    9
    Views:
    2,541
    Karl Heinz Buchegger
    Aug 30, 2004
  3. Jeff Epler
    Replies:
    10
    Views:
    654
    Anton Vredegoor
    Aug 20, 2003
  4. Matt

    "Eight Queens" program

    Matt, Aug 18, 2004, in forum: C Programming
    Replies:
    5
    Views:
    449
    -berlin.de
    Aug 21, 2004
  5. Replies:
    1
    Views:
    377
    Lawrence Kirby
    Jul 6, 2005
Loading...

Share This Page