Path: csiph.com!4.us.feeder.erje.net!feeder.erje.net!feeder.usenetexpress.com!feeder-in1.iad1.usenetexpress.com!border1.nntp.dca1.giganews.com!border2.nntp.dca1.giganews.com!nntp.giganews.com!news.iecc.com!.POSTED.news.iecc.com!nerds-end From: Martin Ward Newsgroups: comp.compilers Subject: Re: Optimization techniques Date: Thu, 25 Apr 2019 16:46:54 +0100 Organization: Compilers Central Lines: 64 Sender: news@iecc.com Approved: comp.compilers@iecc.com Message-ID: <19-04-020@comp.compilers> References: <72d208c9-169f-155c-5e73-9ca74f78e390@gkc.org.uk> Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 8bit Injection-Info: gal.iecc.com; posting-host="news.iecc.com:2001:470:1f07:1126:0:676f:7373:6970"; logging-data="39770"; mail-complaints-to="abuse@iecc.com" Keywords: arithmetic, optimize, comment Posted-Date: 25 Apr 2019 16:14:53 EDT X-submission-address: compilers@iecc.com X-moderator-address: compilers-request@iecc.com X-FAQ-and-archives: http://compilers.iecc.com Xref: csiph.com comp.compilers:2204 David Brown wrote: > And there are undefined behaviours which could be given definitions, but > doing so is not actually a positive thing. The prime example is signed > integer overflow. Since overflowing your integers is almost always an > error in the code anyway, there are no benefits in giving it defined > behaviour. This is completely backwards. If signed overflow was given a defined behaviour (such as the two's complement result), then compilers for CPUs which do not implement two's complement operations would have to generate less efficient code (but does anyone still make such a CPU?). Any program which guarantees not to overflow would be unaffected. Any program which expects a two's complement result could now be relied upon to work correctly, and not suddenly produce random results when the next version of the compuler comes out! Any program which expected a different result (one's complement anyone?) would need additional code. With the current situation, anyone wanting to avoid undefined behaviour (and don't we all?) has to write code like this for any signed operation: signed int sum; if (((si_b > 0) && (si_a > (INT_MAX - si_b))) || ((si_b < 0) && (si_a < (INT_MIN - si_b)))) { /* Handle error */ } else { sum = si_a + si_b; } See: https://wiki.sei.cmu.edu/confluence/display/c/INT32-C.+Ensure+that+operations+on+signed+integers+do+not+result+in+overflow > But mathematical identities such as associativity and commutativity are > valid because signed integer overflow does not happen - thus "a * (b + > c)" can be changed to "(a * b) + (a * c)". The following slide set discusses some of the problems with undefined behaviour starting on slide 43: http://www0.cs.ucl.ac.uk/staff/B.Karp/3007/s2018/lectures/3007-lecture5-C-arith-undef-behav.pdf Examples of problems include privilege elevation exploits and denial of service attacks. There was a discussion about undefined behaviour on this list in March/April last year. Some examples: https://blog.regehr.org/archives/213 https://blog.regehr.org/archives/759 Gcc may optimize out tests for buffer overflows because of integer overflows: https://lwn.net/Articles/278137/ -- Martin Dr Martin Ward | Email: martin@gkc.org.uk | http://www.gkc.org.uk G.K.Chesterton site: http://www.gkc.org.uk/gkc | Erdos number: 4 [I don't think there are any ones complement machines left but there are certainly machines with different word sizes. -John]