Path: ...!news.nobody.at!eternal-september.org!feeder3.eternal-september.org!news.eternal-september.org!.POSTED!not-for-mail From: Tim Rentsch Newsgroups: comp.lang.c Subject: Re: What is your opinion about unsigned int u = -2 ? Date: Sun, 11 Aug 2024 23:07:32 -0700 Organization: A noiseless patient Spider Lines: 38 Message-ID: <86le12ff4r.fsf@linuxsc.com> References: <87mslxe4wj.fsf@bsb.me.uk> <86y152n9c8.fsf@linuxsc.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Injection-Date: Mon, 12 Aug 2024 08:07:32 +0200 (CEST) Injection-Info: dont-email.me; posting-host="f42e4005105099d89c60a754521770ce"; logging-data="3317302"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1/DpL5XaCbOXvYu9+FaFhv4IYfEHQx8kg0=" User-Agent: Gnus/5.11 (Gnus v5.11) Emacs/22.4 (gnu/linux) Cancel-Lock: sha1:qCYtNOcHAIdFuyZ6k5n2gs+7l4k= sha1:UQpuTSxwP7dOFq7uDS+4wip0n1A= Bytes: 2697 Vir Campestris writes: > On 11/08/2024 20:33, Tim Rentsch wrote: > >> Ick. That choice is exactly backwards IMO. Converting -1 to >> an unsigned type always sets all the bits. Converting -1u to >> an unsigned type can easily do the wrong thing, depending >> on the target type. > > "Converting -1 to an unsigned type always sets all the bits" > > In any normal twos complement architecture that's the case. But there > are a few oddballs out there where -1 is +1, except that the dedicated > sign bit is set. What you say is right if the transformation occurs by means of type punning, as for example if we had a union with both a signed int member and an unsigned int member. Reading the unsigned int member after having assigned to the signed int member depends on whether signed int uses ones' complement, two's complement, or signed magnitude. My comment though is about conversion, not about type punning. The rules for conversion (both explicit conversion, when a cast operator is used, and implicit conversion, such as when an assignment is performed (and lots of other places)) are defined in terms of values, not representations. Thus, in this code signed char minus_one = -1; unsigned u = minus_one; unsigned long bigu = minus_one; unsigned long long biggeru = minus_one; printf( " printing unsigned : %u\n", (unsigned) minus_one ); in every case we get unsigned values (of several lengths) with all value bits set, because of the rules for how values are converted between a signed type (such as signed char) and an unsigned type.