Path: csiph.com!eternal-september.org!feeder.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail From: Keith Thompson Newsgroups: comp.lang.c Subject: Re: Is this code considered to transgress the signed overflow purism? Date: Fri, 28 Apr 2017 08:55:10 -0700 Organization: None to speak of Lines: 39 Message-ID: References: <11ea6682-cdee-4513-97c2-6c90b585716a@googlegroups.com> <87o9vi6rql.fsf@bsb.me.uk> <26aee5e9-ed2f-4c6e-af68-b85418c7e641@googlegroups.com> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Injection-Info: mx02.eternal-september.org; posting-host="2e5ec5e1f0fe87e81c65a0e293e55e1b"; logging-data="28983"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1/XecrfJ2scsNQgUF+KcSY0" User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.1 (gnu/linux) Cancel-Lock: sha1:duQjA6I367U8GbaZ8/VsKzbQ3MY= sha1:TRBm7AFqm1r0S57kbIybKYuowEE= Xref: csiph.com comp.lang.c:108667 bartc writes: > On 28/04/2017 00:44, Keith Thompson wrote: [...] >> It can be tempting to use "<<" as a replacement for multiplying by >> a power of 2. For example, one might write `n << 3` rather than >> `n * 8`. But it's UB if n is negative -- and it's usually better >> to write `n * 8` and let the compiler figure out whether it makes >> sense to use a shift instruction. > > With gcc (on my x86 machine), it uses left shift to multiply a signed > int by 8, one that it doesn't know whether it's negative or not. > > It knows that left-shifting a negative int will work. I think it will > always work on two's complement (ie. give the same result as multiply), > and many will spend their entire working lives working with such > machines. Yet they are not allowed to assume that. Ever. You're allowed to assume anything you like -- but you should be aware that your assumptions might not be universally valid, even if your CPU uses 2's-complement. > As for UB on left-shifting 3 places, isn't this the same UB you get when > multiplying by 8 and the result might overflow? In that case it doesn't > seem to matter which is used. No. (-3 * 8) is well defined. (-3 << 8) has undefined behavior. > (BTW why didn't the language just prohibit shifts on signed values if it > frowns upon them so much?) Shifts on *non-negative* signed values are well defined as long as the result is representable in the type. Prohibiting shifts on signed values would make (1 << 3) invalid (you'd have to write (1U << 3)). -- Keith Thompson (The_Other_Keith) kst-u@mib.org Working, but not speaking, for JetHead Development, Inc. "We must do something. This is something. Therefore, we must do this." -- Antony Jay and Jonathan Lynn, "Yes Minister"