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.