Path: csiph.com!news.swapon.de!eternal-september.org!feeder.eternal-september.org!reader01.eternal-september.org!.POSTED!not-for-mail From: Keith Thompson Newsgroups: comp.lang.c Subject: Re: C wish list Date: Fri, 22 Mar 2019 12:29:39 -0700 Organization: None to speak of Lines: 70 Message-ID: References: <11b51bdf-7847-40fc-bdf5-b3777f41b4da@googlegroups.com> <18RkE.296542$DH4.255445@fx24.am4> <2J7lE.185089$1p7.119303@fx05.am4> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Injection-Info: reader02.eternal-september.org; posting-host="7987eac78b6ba844db2ada674c778ee3"; logging-data="32634"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1/s+rPUArsmgE05OOhaM7zP" User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.1 (gnu/linux) Cancel-Lock: sha1:oMVQM02xe84NcoCUTcSQTvTtAqs= sha1:BUfOlMUNZQ8fEHOskO7KGi7LgRc= Xref: csiph.com comp.lang.c:142258 Bart writes: > On 22/03/2019 18:54, Keith Thompson wrote: >> Bart writes: >> [...] >>> You are saying that here: >>> >>> int32_t x = f(); >>> int32_t y = >8> >>> >>> it is acceptable to use a 64-bit version of x, even though x is only 32 >>> bits, because it's using a value left over in a 64-bit register from >>> some immediately prior calculation of x. >>> >>> If that is actually what C allows, then it is even crazier than I'd >>> already thought, and that is saying something. >>> >>> If you are saying that that is only allowed because of UB, then that >>> does little to change my opinion. It is certainly more crazy stuff that >>> the OP is complaining about. >> >> If the evaluation of the expression has undefined behavior, then yes, >> literally anything is allowed. That's what undefined behavior means. >> >> I'm not sure why you chose x>>8 as your example. > > Because it can introduce bits from the top half of a register. No, it can't, because the >> operator is not defined in terms of whatever shift instructions the CPU happens to provide. If x is non-negative, then x>>8 yields the integral part of x/256. If x is negative, the result of x>>8 is implementation-defined. A conforming compiler will do whatever it needs to do to satisfy that requirement. > Take my example, and say f() returns 0xFFFFFFFF_00000000 in 64-bit > register R0. The bottom half is stored to x, so x contains 0. > > The next line is: > > int32_t y = x>>8; > > because R0 could still contain 0xFFFFFFFF_00000000, David Brown is > suggesting that a compiler might make use of that existing value, and > because this processor only has 64-bit ops, it will right shift all 64 > bits to end up with 0x00FFFFFF_FF000000. I don't remember what David suggested. > Then the low half of 0xFF000000 is written to y, rather than zero (ie. > 0>>8). > > This is what I said was crazy, whether it was done for signed/unsigned x > or y, or even only for signed x/y due to UB. You said "due to UB", but you used an example with no undefined behavior. If your example exhibited undefined behavior, then yes, a compiler could generate code that uses garbage from the upper half of a 64-bit register. Feel free to present an example that actually illustrates your point. [...] -- Keith Thompson (The_Other_Keith) kst-u@mib.org Will write code for food. void Void(void) { Void(); } /* The recursive call of the void */