[Bug c++/90186] optimizing options -O1 and -O2 produce different results

austin.card at torchtechnologies dot com gcc-bugzilla@gcc.gnu.org
Wed Apr 24 19:09:00 GMT 2019


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.


More information about the Gcc-bugs mailing list