Padding and alignment

Discussion in 'C++' started by Spoon, Feb 12, 2007.

  1. Spoon

    Spoon Guest

    Hello everyone,

    I had expected my C++ compiler to add padding within classes and structs
    to align fields to their "natural" boundary. This seems not to be true.

    $ cat align.cxx
    #include <cstdio>
    struct foo
    {
    virtual void f() const { }
    long long x;
    };
    int main()
    {
    foo bar;
    printf("%p %p\n", (void *)&bar, (void *)&bar.x);
    return 0;
    }

    $ ./a.out
    0xbfd9da00 0xbfd9da04

    On my platform (x86 Linux g++) long long is 64-bits wide.
    (I suppose the first 4 bytes store the v-pointer.)
    Why didn't the compiler add padding to align x to a 64-bit boundary?

    Regards.
     
    Spoon, Feb 12, 2007
    #1
    1. Advertising

  2. Spoon

    red floyd Guest

    Spoon wrote:
    > Hello everyone,
    >
    > I had expected my C++ compiler to add padding within classes and structs
    > to align fields to their "natural" boundary. This seems not to be true.
    >
    > $ cat align.cxx
    > #include <cstdio>
    > struct foo
    > {
    > virtual void f() const { }
    > long long x;
    > };
    > int main()
    > {
    > foo bar;
    > printf("%p %p\n", (void *)&bar, (void *)&bar.x);
    > return 0;
    > }
    >
    > $ ./a.out
    > 0xbfd9da00 0xbfd9da04
    >
    > On my platform (x86 Linux g++) long long is 64-bits wide.
    > (I suppose the first 4 bytes store the v-pointer.)
    > Why didn't the compiler add padding to align x to a 64-bit boundary?
    >
    > Regards.


    That's an implementation specific issue, having nothing to do with the
    language itself, and is therefore OT in comp.lang.c++. May I suggest
    asking in gnu.g++.help?

    Followups set to gnu.g++.help
     
    red floyd, Feb 12, 2007
    #2
    1. Advertising

  3. Spoon

    Rolf Magnus Guest

    Spoon wrote:

    > Hello everyone,
    >
    > I had expected my C++ compiler to add padding within classes and structs
    > to align fields to their "natural" boundary. This seems not to be true.
    >
    > $ cat align.cxx
    > #include <cstdio>
    > struct foo
    > {
    > virtual void f() const { }
    > long long x;
    > };
    > int main()
    > {
    > foo bar;
    > printf("%p %p\n", (void *)&bar, (void *)&bar.x);
    > return 0;
    > }
    >
    > $ ./a.out
    > 0xbfd9da00 0xbfd9da04
    >
    > On my platform (x86 Linux g++) long long is 64-bits wide.
    > (I suppose the first 4 bytes store the v-pointer.)
    > Why didn't the compiler add padding to align x to a 64-bit boundary?


    What makes you think it should? Generally, C++ doesn't dictate any
    alingment. On some 32 bit systems, the maximum needed alignment is 32 bits,
    so why waste memory by using an alignment greater than needed if you don't
    gain anything from it?
    I'm writing C++ code for an 8 bit platform which doesn't have any specific
    alignment reqirements, so every type is byte aligned.
     
    Rolf Magnus, Feb 12, 2007
    #3
  4. Spoon

    Grizlyk Guest

    Spoon wrote:
    >
    > struct foo
    > {
    > virtual void f() const { }
    > long long x;
    > };
    >
    > int main()
    > {
    > foo bar;
    > printf("%p %p\n", (void *)&bar, (void *)&bar.x);
    > return 0;
    > }
    >
    > $ ./a.out
    > 0xbfd9da00 0xbfd9da04
    >
    > On my platform (x86 Linux g++) long long is 64-bits wide.
    > (I suppose the first 4 bytes store the v-pointer.)


    Wait.
    1. What is v-pointer?
    2. Why member foo::x has nonzero offset from foo memory start?

    --
    Maksim A. Polyanin

    "In thi world of fairy tales rolls are liked olso"
    /Gnume/
     
    Grizlyk, Feb 12, 2007
    #4
  5. Spoon

    Pan Guest

    Rolf Magnus wrote:

    > > On my platform (x86 Linux g++)

    > I'm writing C++ code for an 8 bit platform which doesn't have any specific
    > alignment reqirements, so every type is byte aligned.


    BTW, x86 architecture don't have specific alignment requirements, too.

    --
    Marco
     
    Pan, Feb 12, 2007
    #5
  6. Spoon

    red floyd Guest

    Grizlyk wrote:


    DISCLAIMER: THIS IS OFF-TOPIC, AS THE STANDARD DOES NOT DISCUSS
    VPTR/VTBL MECHANISMS.

    However, as most, if not all, implementations use it....

    > 1. What is v-pointer?

    Pointer to the virtual function table for the class (not required by the
    standard, but most known implementations do this).

    > 2. Why member foo::x has nonzero offset from foo memory start?

    For the vptr. Each object with virtual functions in g++ -- again, not
    required by the STandard -- has a pointer to a per-class table which
    contains the addresses of the virtual functions for that class. It
    generally lives at the start of the class, hence the rationale behind
    foo::x not having 0 offset.
     
    red floyd, Feb 12, 2007
    #6
  7. Spoon

    Grizlyk Guest

    red floyd wrote:
    >
    > However, as most, if not all, implementations use it....
    >
    >> 1. What is v-pointer?

    > Pointer to the virtual function table for the class (not required by the
    > standard, but most known implementations do this).
    >
    >> 2. Why member foo::x has nonzero offset from foo memory start?

    > For the vptr. Each object with virtual functions in g++ -- again, not
    > required by the STandard -- has a pointer to a per-class table which
    > contains the addresses of the virtual functions for that class. It
    > generally lives at the start of the class, hence the rationale behind
    > foo::x not having 0 offset.


    For the first, there are no virtual functions declared in the class, so no
    vtable exist.

    For the second, I have read many times, that C++ classes have designed to be
    similar to C structures, so C++ data is very like to C-structure, but
    C-structure has zero offset for first member and has well-defined theorder
    of the members.

    I do not think, that the equality is important or needed, but to make it,
    for C++ extra hidden data, as pointer to vtable and so on, because of sizeof
    of all visible data is known at compile time, all extra hidden data can be
    placed _after_ all. For inherited classes new data can be placed after all
    data of base class. But may be pointer to vtable befor all data is more
    regular than pointer to vtable mixed with data.

    --
    Maksim A. Polyanin

    "In thi world of fairy tales rolls are liked olso"
    /Gnume/
     
    Grizlyk, Feb 12, 2007
    #7
  8. Spoon

    Robert Mabee Guest

    Rolf Magnus wrote:
    > Generally, C++ doesn't dictate any
    > alingment. On some 32 bit systems, the maximum needed alignment is 32 bits,
    > so why waste memory by using an alignment greater than needed if you don't
    > gain anything from it?
    > I'm writing C++ code for an 8 bit platform which doesn't have any specific
    > alignment reqirements, so every type is byte aligned.


    It's often recommended to align primitive types same as their size (if
    not silly like 80 bit floating point). This comes from sad experience
    with CPUs that evolve to wider busses, making the former two-word type
    either inefficient or fatal to access on the "wrong" alignment. An
    otherwise compatible CPU requires painful coding to use such things as
    structures saved on disk.

    Sounds like a short-sighted mistake in adding 64 bit types to the x86
    compiler. Too late to fix it. It is now up to the user to craft any
    structure that might be permanent or exported so that it has explicit
    padding to this "natural" alignment. Probably it makes no sense to
    export an object with a vtable pointer in a raw form so its effect on
    alignment can be ignored.
     
    Robert Mabee, Feb 12, 2007
    #8
  9. Spoon

    red floyd Guest

    Grizlyk wrote:
    > red floyd wrote:
    >
    >
    > For the first, there are no virtual functions declared in the class, so no
    > vtable exist.
    >


    Really? From the OP:

    > struct foo
    > {
    > virtual void f() const { }
    > long long x;
    > };



    > For the second, I have read many times, that C++ classes have designed to be
    > similar to C structures, so C++ data is very like to C-structure, but
    > C-structure has zero offset for first member and has well-defined theorder
    > of the members.
    >


    Only for POD.
     
    red floyd, Feb 12, 2007
    #9
  10. Spoon

    red floyd Guest

    Grizlyk wrote:

    > For the first, there are no virtual functions declared in the class, so no
    > vtable exist.


    Really? From the OP:

    > struct foo
    > {
    > virtual void f() const { }
    > long long x;
    > };
    >
    > For the second, I have read many times, that C++ classes have designed to be
    > similar to C structures, so C++ data is very like to C-structure, but
    > C-structure has zero offset for first member and has well-defined theorder
    > of the members.
    >


    Only for POD.
     
    red floyd, Feb 12, 2007
    #10
  11. Spoon

    Grizlyk Guest

    red floyd wrote:
    >>
    >> For the first, there are no virtual functions declared in the class, so
    >> no vtable exist.

    >
    > Really? From the OP:
    >
    > > struct foo
    > > {
    > > virtual void f() const { }
    > > long long x;
    > > };


    Hmm? I did not see. If virtual exist vtable must be.

    --
    Maksim A. Polyanin

    "In thi world of fairy tales rolls are liked olso"
    /Gnume/
     
    Grizlyk, Feb 12, 2007
    #11
  12. Spoon

    Rolf Magnus Guest

    Pan wrote:

    > Rolf Magnus wrote:
    >
    >> > On my platform (x86 Linux g++)

    >> I'm writing C++ code for an 8 bit platform which doesn't have any
    >> specific alignment reqirements, so every type is byte aligned.

    >
    > BTW, x86 architecture don't have specific alignment requirements, too.


    It depends. Some instructions are slower when used on misaligned data, some
    won't work at all.
     
    Rolf Magnus, Feb 12, 2007
    #12
  13. Spoon

    Rolf Magnus Guest

    Grizlyk wrote:

    > For the second, I have read many times, that C++ classes have designed to
    > be similar to C structures, so C++ data is very like to C-structure, but
    > C-structure has zero offset for first member and has well-defined theorder
    > of the members.


    POD ("plain old data") classes in C++ have that, too. Basically, a
    simplified definition of "POD" is "similar to what C would do". Adding a
    virtual member function makes your class non-POD.
     
    Rolf Magnus, Feb 13, 2007
    #13
    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. Ninan Thomas
    Replies:
    3
    Views:
    432
    Kevin Goodsell
    Aug 22, 2003
  2. SenderX
    Replies:
    2
    Views:
    876
    perry
    May 13, 2004
  3. Paul_Huang

    Memory Padding and alignment

    Paul_Huang, Sep 21, 2004, in forum: C++
    Replies:
    2
    Views:
    3,992
    Serge Paccalin
    Sep 21, 2004
  4. Ninan Thomas
    Replies:
    3
    Views:
    1,964
    Kevin Goodsell
    Aug 22, 2003
  5. Andrew Tomazos
    Replies:
    7
    Views:
    878
    Richard Herring
    Jun 24, 2009
Loading...

Share This Page