//alignment.cpp
#include <iostream>

struct Struct_containing_64aligned_member {
    Struct_containing_64aligned_member()
    : aligned_var(80)
    {}
    uint64_t aligned_var __attribute__((aligned(64)));
};

struct Struct_no_aligned_member {
    Struct_no_aligned_member()
    : var(80)
    {}
    uint64_t var;
};


int main()
{
    Struct_no_aligned_member *s1 = new Struct_no_aligned_member();
    Struct_containing_64aligned_member *s2 = new
Struct_containing_64aligned_member();

    std::cout << "alignof(Struct_no_aligned_member) : " <<
alignof(Struct_no_aligned_member)   << '\n' ;
    std::cout << "alignof(Struct_containing_64aligned_member) : " <<
alignof(Struct_containing_64aligned_member)   << '\n' ;
    std::cout << "alignof(*s1) : " << alignof(*s1)   << '\n' ;
    std::cout << "alignof(*s2) : " << alignof(*s2)   << '\n' ;

    std::cout << "s1 = " << s1 << "\n";
    std::cout << "s2 = " << s2 << "\n";

    std::cout << "&*s1 = " << &*s1 << "\n";
    std::cout << "&*s2 = " << &*s2 << "\n";

    std::cout << "&*s1 % 0x40 = " << (uint64_t)&*s1 % 0x40 << "\n";
    std::cout << "&*s2 % 0x40= " << (uint64_t)&*s2 % 0x40 << "\n";


    std::cout << "&s1->var = " << &s1->var << "\n";
    std::cout << "&s2->aligned_var = " << &s2->aligned_var << "\n";

    std::cout << "&s1->var % 0x40 = 0x" << std::hex
<<(uint64_t)&s1->var % 0x40 << "\n";
    std::cout << "&s2->aligned_var % 0x40  = 0x" << std::hex <<
(uint64_t)&s2->aligned_var % 0x40 << "\n";
}


g++ -std=c++11 -Wall -g  alignment.cpp -o alignment



alignof(Struct_no_aligned_member) : 8
alignof(Struct_containing_64aligned_member) : 64
alignof(*s1) : 8
alignof(*s2) : 64
s1 = 0x199c010
s2 = 0x199c030
&*s1 = 0x199c010
&*s2 = 0x199c030
&*s1 % 0x40 = 16
&*s2 % 0x40= 48
&s1->var = 0x199c010
&s2->aligned_var = 0x199c030
&s1->var % 0x40 = 0x10
&s2->aligned_var % 0x40  = 0x0

Surprised me that &s2->aligned_var % 40 was not calculated as 0x30
given its address.

I suspect something related to this resulted in a segfault for me.
with -O3 -march=corei7-avx gcc thought 4 consecutive 64 bit integers
were aligned to 256 bits and could be initialised with a vmovdqa
instruction. This was incorrect as the structure was on the heap and
the alloc was not aligned using posix_memalign() or similar but gcc
seems to have calculated offsets as though it were aligned.

Not sure if this is the intended behaviour for an object on the heap
with an aligned member and the docs need updating to include the
gotcha or if this is working differently to intended. Interested to
hear people's thinking.


Centos 6.4 with gcc-4.8.2 from Scientific Gnu/Linux CERN 6
(same behaviour evident on ubuntu 14.04 gnu/linux gcc 4.8.2)

 g++ -v
Using built-in specs.
COLLECT_GCC=g++
COLLECT_LTO_WRAPPER=/opt/centos/devtoolset-2/root/usr/bin/../libexec/gcc/x86_64-redhat-linux/4.8.2/lto-wrapper
Target: x86_64-redhat-linux
Configured with: ../configure --prefix=/opt/rh/devtoolset-2/root/usr
--mandir=/opt/rh/devtoolset-2/root/usr/share/man
--infodir=/opt/rh/devtoolset-2/root/usr/share/info
--with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-bootstrap
--enable-shared --enable-threads=posix --enable-checking=release
--with-system-zlib --enable-__cxa_atexit
--disable-libunwind-exceptions --enable-gnu-unique-object
--enable-linker-build-id --enable-languages=c,c++,fortran,lto
--enable-plugin --with-linker-hash-style=gnu --enable-initfini-array
--disable-libgcj
--with-isl=/builddir/build/BUILD/gcc-4.8.2-20140120/obj-x86_64-redhat-linux/isl-install
--with-cloog=/builddir/build/BUILD/gcc-4.8.2-20140120/obj-x86_64-redhat-linux/cloog-install
--with-mpc=/builddir/build/BUILD/gcc-4.8.2-20140120/obj-x86_64-redhat-linux/mpc-install
--with-tune=generic --with-arch_32=i686 --build=x86_64-redhat-linux
Thread model: posix
gcc version 4.8.2 20140120 (Red Hat 4.8.2-15) (GCC)

Reply via email to