Path: csiph.com!eternal-september.org!reader02.eternal-september.org!.POSTED!not-for-mail
From: Tim Rentsch
Newsgroups: comp.lang.c
Subject: Re: does a double cast to unsigned makes sense in any circumstance?
Date: Sat, 15 Jan 2022 18:53:07 -0800
Organization: A noiseless patient Spider
Lines: 56
Message-ID: <86y23gtmr0.fsf@linuxsc.com>
References: <86czl8kaew.fsf@levado.to>
Mime-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Injection-Info: reader02.eternal-september.org; posting-host="66ee21d996f56235c8cdb5e1ea47e716"; logging-data="18658"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1+aBhnbKo7S0+2AriiANVbI6NCOCNbRxUg="
User-Agent: Gnus/5.11 (Gnus v5.11) Emacs/22.4 (gnu/linux)
Cancel-Lock: sha1:LlvZUS37giR0Jgkn9R+sFIp8yJw= sha1:LD1SJ4AkCpuEkwlo0YpwfYX3YIU=
Xref: csiph.com comp.lang.c:164424
Meredith Montgomery writes:
> I've seen this somewhere or I wrote this some time in the past for some
> reason and I can't see how this make sense any longer. In a procedure
> to read a numeric string and turn it into a number, we need to convert
> each char-digit to some kind of integer:
>
> (uint64_t) (unsigned char) (s[pos] - '0');
>
> But the double cast here seems odd. I could have written this by
> copying it from somewhere else. Today, what I would write is just
>
> (uint64_t) (s[pos] - '0');
>
> Am I making a mistake now? I can't anything wrong with this. Isn't a
> char just an int? I'm turning an int into an unsigned integer (of a
> larger size).
The original context for the expression in question is this
function:
> [posted by Meredith Montgomery]
>
> #include
> #include
>
> int scan_ulong(register char *s, register unsigned long *u)
> {
> register unsigned int pos;
> register unsigned long r;
> register unsigned long c;
>
> pos = 0; r = 0;
>
> for ( ;; ) {
> c = (unsigned long) (unsigned char) (s[pos] - '0');
> if (c < 10) {
> if( ((ULONG_MAX - c) / 10) >= r)
> r = r * 10 + c;
> else return -1; /* lack of space */
> ++pos; continue;
> }
> break;
> }
>
> *u = r;
> return pos;
> }
In this context, the casts are superfluous. Just write
c = s[pos] - '0';
and the right thing will happen, because the assignment to 'c'
converts the value on the right hand side to 'unsigned long',
and so takes care of any negative values.