https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90186
--- Comment #2 from austin.card at torchtechnologies dot com --- (In reply to Richard Biener from comment #1) > Note that using #pragma pack(1) on struct Ipv4 makes u_short members not > naturally aligned and thus code like > > void UpdateChecksum() > { > u_long sum(0); > > SetChecksum(0); > > u_short *buf = (u_short*)ip->Payload(); > u_long nwords = ip->PayloadSize() / 2; > > for (unsigned i = 0; i < nwords; ++i) > { > > sum += ntohs(*buf++); > > dereferences pointers to u_short that might not be aligned to a 2 byte > boundary. > > Confirmed though, even when using -fno-inline. -fno-strict-aliasing fixes > it. Possibly the very same issue above - using u_short * to access memory > with a different dynamic type. The same happens here: > > buf = (u_short*)&ph; > nwords = 6; > > for (unsigned i = 0; i < nwords; ++i) > { > > sum += ntohs(*buf++); > > ph is of type PseudoHeader. You cannot use lvalues of type u_short to > refer to them. So if this is an alignment issue, How does the #pragma pack(1) change the alignment differently between option -O1 and -O2? Also in Udp.h if I uncomment the dummy function at line 147, then the code produces the same output between -O1 and -O2. I have tried to produce the same result with other compilers: clang++ -std=c+11 -O2 -o CheckSum main.cpp CheckSum.cpp clang++ -std=c+11 -O1 -o CheckSum main.cpp CheckSum.cpp does not have this problem. And Microsoft VS2017 compiler does not have this problem between Debug and Release. Lastly, the code provided is computing the 16-bit checksum of a UDP packet header contained in an IPv4 network packet. While the comment regarding alignment of u_short members is in general correct, any misaligned members are intended by the RFC standards.