Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.programming > #6078

Re: Here is why C++ and C are bad...

From Richard Heathfield <rjh@cpax.org.uk>
Newsgroups comp.programming
Subject Re: Here is why C++ and C are bad...
Date 2015-12-30 13:28 +0000
Organization A noiseless patient Spider
Message-ID <n60m14$lf$1@dont-email.me> (permalink)
References <n5kdn4$cji$1@dont-email.me> <n5uqdd$gin$1@dont-email.me> <n5v0di$7i3$1@dont-email.me> <n5v0p5$8s3$1@dont-email.me> <n6063m$ccb$1@dont-email.me>

Show all headers | View raw


On 30/12/15 08:56, David Brown wrote:
> On 29/12/15 23:19, Richard Heathfield wrote:

<snip>

>> 2) mixing of signed and unsigned expressions is very often a sign that
>> the program hasn't been thought through properly. This, too, is (I
>> think) a discussion that might also turn out to be profitable, despite
>> its origins.
>
> Perhaps that could usefully be discussed here, since it is an issue that
> can affect many languages.

Oddly, the signed/unsigned dilemma is one that can bite us even if we 
are only dealing exclusively (or so we think) with unsigned values. 
Recently, in Another Place, I suggested capturing a value that is 
inherently unsigned, and small (it may have been an array size - I don't 
remember the exact details), by using strtoul.

Here is a sketch of the mechanism I suggested:

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char **argv)
{
   if(argc > 1)
   {
     char *endptr = NULL;
     unsigned long n = strtoul(argv[1], &endptr, 10);
     if(endptr > argv[1])
     {
       printf("%lu\n", n);
     }
     else
     {
       puts("That's a terrible argument!");
     }
   }
   else
   {
     puts("Argue more.");
   }
   return 0;
}

Looks innocuous enough, doesn't it? But if I call it like this:

./foo -1

I get an output of 18446744073709551615 (!)

This surprised me for two reasons - firstly, I genuinely wasn't aware 
that unsigned long is 64 bits on this system. (Why should I care, after 
all? As long as it is at least 32 bits, I'm happy.) But more 
importantly, what I was expecting was an output of "That's a terrible 
argument!" But what I actually got was a value that is difficult to 
envisage as an array size.

(Obviously it's easy to fix this - we can simply check that the first 
non-whitespace character in the string is a digit in the relevant number 
base.)

But that isn't, quite, what we were talking about.

The following code is perhaps a warning of the perils of arbitrarily 
mixing up signed and unsigned quantities:

#include <stdio.h>

int main(void)
{
   int i = -6;
   unsigned int j = 42;
   if(i < j)
   {
     puts("-6 is less than 42");
   }
   else
   {
     puts("-6 is greater than or equal to 42");
   }
   return 0;
}

If it weren't for the fact that we were talking about the perils of 
signed and unsigned arithmetic, one might reasonably expect the code to 
print "-6 is less than 42", but of course it doesn't do that.

This is a consequence of one of the "usual arithmetic conversions" - 
when the int value -6 is compared to the unsigned int value 42, it is 
first promoted to unsigned int, and of course this means that it is not 
only greater than 42 but in fact very, very, very much greater!

I think it is unfortunate that many C programmers tend to gloss over the 
"usual arithmetic conversions" on the grounds that, almost all the time, 
they make perfect sense and behave in exactly the way we expect and do 
everything we want. It is certainly a tendency to which I have succumbed 
on occasion. But *sometimes* they bite.

-- 
Richard Heathfield
Email: rjh at cpax dot org dot uk
"Usenet is a strange place" - dmr 29 July 1999
Sig line 4 vacant - apply within

Back to comp.programming | Previous | Next — Previous in thread | Next in thread | Find similar | Unroll thread


Thread

Re: Here is why C++ and C are bad... Richard Heathfield <rjh@cpax.org.uk> - 2015-12-29 20:31 +0000
  Re: Here is why C++ and C are bad... Kaz Kylheku <kaz@kylheku.com> - 2015-12-29 21:20 +0000
  Re: Here is why C++ and C are bad... David Brown <david.brown@hesbynett.no> - 2015-12-29 23:13 +0100
    Re: Here is why C++ and C are bad... Richard Heathfield <rjh@cpax.org.uk> - 2015-12-29 22:19 +0000
      Re: Here is why C++ and C are bad... David Brown <david.brown@hesbynett.no> - 2015-12-30 09:56 +0100
        Re: Here is why C++ and C are bad... Richard Heathfield <rjh@cpax.org.uk> - 2015-12-30 13:28 +0000
          Re: Here is why C++ and C are bad... David Brown <david.brown@hesbynett.no> - 2015-12-30 14:55 +0100
            Re: Here is why C++ and C are bad... Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-12-30 16:32 +0000
              Re: Here is why C++ and C are bad... David Brown <david.brown@hesbynett.no> - 2015-12-30 18:17 +0100
                Re: Here is why C++ and C are bad... Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-12-30 20:01 +0000
          Re: Here is why C++ and C are bad... Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-12-30 15:48 +0000
            Re: Here is why C++ and C are bad... Richard Heathfield <rjh@cpax.org.uk> - 2015-12-30 16:35 +0000
              Re: Here is why C++ and C are bad... David Brown <david.brown@hesbynett.no> - 2015-12-30 18:19 +0100
                Re: Here is why C++ and C are bad... Richard Heathfield <rjh@cpax.org.uk> - 2015-12-30 17:39 +0000
                Re: Here is why C++ and C are bad... Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-12-30 20:26 +0000
              Re: Here is why C++ and C are bad... "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> - 2015-12-30 18:32 +0100
              Re: Here is why C++ and C are bad... Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-12-30 19:55 +0000
                Re: Here is why C++ and C are bad... Richard Heathfield <rjh@cpax.org.uk> - 2015-12-30 20:15 +0000
                Re: Here is why C++ and C are bad... Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-12-30 22:00 +0000
      Re: Here is why C++ and C are bad... Ian Collins <ian-news@hotmail.com> - 2015-12-31 10:16 +1300

csiph-web