Path: csiph.com!eternal-september.org!feeder.eternal-september.org!nntp.eternal-september.org!.POSTED!not-for-mail
From: Tim Rentsch
Newsgroups: comp.arch
Subject: Re: endian history
Date: Sat, 03 Oct 2026 05:29:42 -0700
Organization: A noiseless patient Spider
Lines: 67
Message-ID: <86qzi7m0g9.fsf@linuxsc.com>
References: <10uks4f$1dqo$1@gal.iecc.com> <118jitv$1cm6b$1@dont-email.me> <86ik42tcf4.fsf@linuxsc.com> <118uf6m$12tta$1@dont-email.me> <86ld8srnq9.fsf@linuxsc.com> <1790188863-5857@newsgrouper.org> <86cxu3sp11.fsf@linuxsc.com> <1790269240-5857@newsgrouper.org> <119hf66$3nmbu$1@dont-email.me> <86ld8hplkd.fsf@linuxsc.com> <2026Oct1.172040@mips.complang.tuwien.ac.at> <864if5pfby.fsf@linuxsc.com> <2026Oct1.183612@mips.complang.tuwien.ac.at> <1790884534-5857@newsgrouper.org> <119nt2j$1rmn1$5@dont-email.me> <20261002124718.000076c1@yahoo.com>
MIME-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Injection-Date: Sat, 03 Oct 2026 12:29:47 +0000 (UTC)
Injection-Info: dont-email.me; logging-data="3161321"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1+w9TnUlvKZRu6viVoDAlMZ7uG1I+mURU8="; posting-host="b0e28b4afc9fd8b2450f610d134fbfb4"
User-Agent: Gnus/5.11 (Gnus v5.11) Emacs/22.4 (gnu/linux)
Cancel-Lock: sha1:vd3UAY01rJhGmPlqC+BpXt2e9/M= sha1:4BcHJ7o9z8ZFAAZd/S140ZC48Jw= sha256:zQEdyvKqF1MTMdLm7AjywmqWwNd8uAA79zvForLjqXs= sha1:nJsv4KiMd5PQ7qFCqF/pERXrHkY= sha256:6Bsg3aJ8hRgkKAIoehAWbxvk0hp/5CxTp6SJK3X0jxc=
Xref: csiph.com comp.arch:118425
Michael S writes:
> On Fri, 2 Oct 2026 11:21:23 +0200
> David Brown wrote:
>
>> On 01/10/2026 21:55, MitchAlsup wrote:
[...]
>>> Which means you cannot write::
>>>
>>> for( int i = 1; i; i<<=1 )
>>> { ... }
>>> // never gets here--traps instead.
>>
>> You can write it if you like - but it is UB on all platforms.
>>
>> Use "unsigned int" here. Then there is no problem.
>
> It is not UB if compiler defines the meaning.
This isn't right. In the context of C, "undefined behavior" has
a specific meaning, defined by the ISO standard. If the standard
says a particular construct has undefined behavior, it still has
undefined behavior even if an implementation documents what the
concrete behavior would be. "Undefined behavior" does not mean
the concrete behavior is unpredictable; it means only that each
implementation is free to do as it chooses.
> AFAIK, it is defined for gcc, even in absence of special flags.
> From the manual:
>
> "The results of some bitwise operations on signed integers (C90
> 6.3, C99 and C11 6.5, C23 6.5.1).
>
> Bitwise operators act on the representation of the value including
> both the sign and value bits, where the sign bit is considered
> immediately above the highest-value value bit. Signed >> acts
> on negative numbers by sign extension.
>
> As an extension to the C language, GCC does not use the latitude
> given in C99 and later to treat certain aspects of signed << as
> undefined. However, -fsanitize=shift (and -fsanitize=undefined)
> will diagnose such cases. They are also diagnosed where constant
> expressions are required."
It looks like the gcc documentation is making the same mistake of
interpreting "undefined behavior" as meaning "unpredictable
behavior". In fact gcc IS taking advantage of signed << having
undefined behavior in certain cases, to implement a particular
concrete behavior in those cases.
> I don't like the style of writing of the last paragraph, but the
> meanaing seems to be that gcc defines 'i << e' to be the same as
> '(int)((unsigned)i << e)'
The gcc writing is informal rather than being technically precise.
That might be a better choice considering the expected audience.
That said, I think a more faithful interpretation of what the
documentation says, assuming that a type definition
typedef union { signed int si; unsigned int ui; } SIUI;
has been done, is that 'i << e' is taken to mean
(SIUI){ .ui = (SIUI){ .si = i }.ui << e }.si
so as to act on representations rather than having to deal with the
uncertainties of inter-type conversions.