Path: csiph.com!weretis.net!feeder6.news.weretis.net!feeder.usenetexpress.com!feeder-in1.iad1.usenetexpress.com!border1.nntp.dca1.giganews.com!nntp.giganews.com!news.iecc.com!.POSTED.news.iecc.com!nerds-end From: David Brown Newsgroups: comp.compilers Subject: Re: Optimization techniques and undefined behavior Date: Tue, 7 May 2019 16:38:32 +0200 Organization: A noiseless patient Spider Lines: 94 Sender: news@iecc.com Approved: comp.compilers@iecc.com Message-ID: <19-05-053@comp.compilers> References: <72d208c9-169f-155c-5e73-9ca74f78e390@gkc.org.uk> <19-04-021@comp.compilers> <19-04-024@comp.compilers> <19-04-038@comp.compilers> <19-05-010@comp.compilers> Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit Injection-Info: gal.iecc.com; posting-host="news.iecc.com:2001:470:1f07:1126:0:676f:7373:6970"; logging-data="27122"; mail-complaints-to="abuse@iecc.com" Keywords: standards, errors Posted-Date: 07 May 2019 18:47:26 EDT X-submission-address: compilers@iecc.com X-moderator-address: compilers-request@iecc.com X-FAQ-and-archives: http://compilers.iecc.com Content-Language: en-GB Xref: csiph.com comp.compilers:2288 On 02/05/2019 19:18, Kaz Kylheku wrote: > On 2019-04-28, David Brown wrote: >> On 26/04/2019 04:26, Kaz Kylheku wrote: >>> On 2019-04-25, David Brown wrote: >>>> It knows that "x * 2 / 2" is "x". It knows that "x + 1 > x" is true. >>> >>> Also, we could have it so that multiplication wraps, and yet in the same >>> breath allow algebraic reductions like this anyway. >>> >>> Basically it can be so that, if overflow takes place in the abstract >>> semantics of "x * 2 / 2", the result can be either the truncated >>> version, or just x, if the algebraic reduction took place. >>> >> >> I am afraid I don't understand you here. Are you saying that you could >> define the language's arithmetic so that, given "x * 2 / 2", the >> compiler could return /either/ "x" or the result you would get from >> wrapped overflow calculations? You are defining two possible "correct" >> answers? > > I'm fairly comfortable with this, because it maps to the familiar ISO C > concept of "unspecified behavior". OK. I can appreciate that, and would consider "signed integer overflow has unspecified behaviour" as a reasonable choice. > > For instance, this program can produce one of the results -12, -6, -2 > or 4, based on which of the six permutations over the order in which the > three functions are called. > > #include > > int x = 1; > > int add2(void) > { > x += 2; > return 0; > } > > int mul4(void) > { > x *= 4; > return 0; > } > > int neg(void) > { > x = -x; > return 0; > } > > void dummy(int a, int b, int c) > { > } > > int main() > { > dummy(add2(), mul4(), neg()); > printf("%d\n", x); > } > > Unspecified behavior isn't exactly wonderful, but it's better than > undefined behavior. > It /can/ be better, but it is not always better. People often misunderstand what unspecified behaviour means. For example, it is possible for different runs of your program here to produce different results - unspecified results don't need to be consistent on different runs. But if you write: int main() { dummy(add2(), mul4(), neg()); if (x == 4) printf("X is 4\n"); if (x != 4) printf("X is not 4\n"); } then for any run of the program, one of the two statements must be printed. If "dummy" had undefined behaviour, /neither/ of them would have to be printed. So undefined behaviour can give more optimisation opportunities (not that they are helpful in this case). And with dummy() giving unspecified behaviour, the compiler will accept the code without complaint - otherwise you'd get endless realms of false positive warnings. But if dummy() had undefined behaviour, a compiler can warn you of your bug. Still, I agree that unspecified values could sometimes be a nice alternative.