https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66730
Bug ID: 66730 Summary: Optimizer seems to make incorrect assumptions about function alignment Product: gcc Version: 4.8.4 Status: UNCONFIRMED Severity: major Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: kustermann.martin at gmail dot com Target Milestone: --- Here is a reproduction of the problem $ cat repro.cc #include <stdio.h> void Foobar() { } int main(int argc, char** argv) { unsigned long lowest_bit = reinterpret_cast<unsigned long>(&Foobar) & 1; printf("Lowest bit of %p is %ld\n", &Foobar, lowest_bit); return 0; } I expect this to print the address of the function and the lowest bit of that address. Despite this assumption, the lowest bit is wrong: $ g++ -O1 -o repro repro.cc $ ./repro Lowest bit of 0x40052d is 0 $ python > bin(0x40052d) '0b10000000000010100101101' So the function is not 2-byte aligned, but the lowest bit gets reported as being 0. => Either the functions must be guaranteed to have a proper alignment or the optimizer cannot make alignment assumptions. $ objdump -d repro ... 000000000040055f <main>: 40055f: 48 83 ec 08 sub $0x8,%rsp 400563: b9 00 00 00 00 mov $0x0,%ecx 400568: ba 5d 05 40 00 mov $0x40055d,%edx 40056d: be 14 06 40 00 mov $0x400614,%esi 400572: bf 01 00 00 00 mov $0x1,%edi 400577: b8 00 00 00 00 mov $0x0,%eax 40057c: e8 df fe ff ff callq 400460 <__printf_chk@plt> 400581: b8 00 00 00 00 mov $0x0,%eax 400586: 48 83 c4 08 add $0x8,%rsp 40058a: c3 retq 40058b: 0f 1f 44 00 00 nopl 0x0(%rax,%rax,1) ... Beginning with optimization level '-O2' the problem seems to go away, since the function is then properly aligned (not sure if this is guaranteed or not). $ g++ --version g++ (Ubuntu 4.8.4-2ubuntu1~14.04) 4.8.4 Copyright (C) 2013 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For reference with clang, this produces $ clang repro.cc -o repro $ ./repro Lowest bit of 0x400530 is 0 $ clang --version clang version 3.7.0 (trunk 239765) Target: x86_64-unknown-linux-gnu Thread model: posix The workaround for us at the moment is to use an attribute: void __attribute__((aligned(4))) Foobar() {}