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


Groups > comp.programming > #6073 > unrolled thread

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

Started byRichard Heathfield <rjh@cpax.org.uk>
First post2015-12-29 20:31 +0000
Last post2015-12-31 10:16 +1300
Articles 20 — 6 participants

Back to article view | Back to comp.programming

This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by below is the oldest one visible, not the original post.


Contents

  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

#6073 — Re: Here is why C++ and C are bad...

FromRichard Heathfield <rjh@cpax.org.uk>
Date2015-12-29 20:31 +0000
SubjectRe: Here is why C++ and C are bad...
Message-ID<n5uqdd$gin$1@dont-email.me>
On 26/12/15 00:54, Ramine wrote:
>
> Hello,
>
> I was working on a project in C++, but i have encountered
> a problem with the language that we call C++, this problem
> is inherent to C++ and C, here is a small example that
> shows the problem:
>
> ===
>
> #include <iostream>
> using namespace std;

This is a very bad idea. The *whole point* of namespaces is to avoid 
name clashes. What you should do (and indeed what you *do* do) is to use 
the std:: prefix for symbols that you pull in from the std namespace. So 
you don't need using namespace std at all! Just remove it.

>
> int main()
> {
>   unsigned int u = 1234;
> int i = -1233;

What does u represent? Why is it unsigned?

What does i represent? Why is it signed?

>
> unsigned int result1 = u + i;

Why are you adding a signed quantity to an unsigned quantity?

>    std::cout << "Number is = " << result1 <<   std::endl;
>
> }
>
> ==
>
>
> In this example, C++ and C will convert i from a signed int type to
> unsigned int type but this is not good ,

It's bad code. C and C++ let you write bad code because, if they didn't, 
a heck of a lot of useful programs would never get written. (There are 
only so many good programmers to go round.) So the onus is on you to 
write good code.

> because this types of
> conversion can cause bugs and errors of logic ,

Then don't do it!

Your article says a lot more about your programming style than it does 
about either C or C++.

-- 
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

[toc] | [next] | [standalone]


#6074

FromKaz Kylheku <kaz@kylheku.com>
Date2015-12-29 21:20 +0000
Message-ID<20151229131302.548@kylheku.com>
In reply to#6073
On 2015-12-29, Richard Heathfield <rjh@cpax.org.uk> wrote:
> On 26/12/15 00:54, Ramine wrote:
>>
>> Hello,
>>
>> I was working on a project in C++, but i have encountered
>> a problem with the language that we call C++, this problem
>> is inherent to C++ and C, here is a small example that
>> shows the problem:
>>
>> ===
>>
>> #include <iostream>
>> using namespace std;
>
> This is a very bad idea. The *whole point* of namespaces is to avoid 
> name clashes. What you should do (and indeed what you *do* do) is to use 
> the std:: prefix for symbols that you pull in from the std namespace. So 
> you don't need using namespace std at all! Just remove it.

Indeed, "using namespace std" means "bring into my namespace here
all symbols in std, current and future, vendor-specific and standard".

It's a transition mechanism for programmers who want namespaces to
go away and deal with clashes, or who want to do a quick and dirty
port of pre-namespace C++ code to namespaces.

Of course, the "using namespace" mechanism is perfectly useful, if namespaces
are sanely designed by someone who pins down the exact contents. For instance:

  namespace foo_api {
    // everything

    int a, b, c, d, e;
    void f(), g(), h();

    // Only a and f existed in the 1.0 API
    namespace v1_0 {
      using foo_api::a;
      using foo_api::f;
    }

    // 2.0 has all of 1.0 plus c, and g.
    namespace v2_0 {
      using namespace foo_api::v1_0;
      using foo_api::c;
      using foo_api::g;
    }

    // 3.0 has everything.
    // (In the future it won't!)
    namespace v3_0 {
      using namespace foo_api;
    }
  }

Now you can do "using namespace foo_api::v1_0" with the confidence
that you're getting an exact, documented set of identifier which shall
never change.

[toc] | [prev] | [next] | [standalone]


#6075

FromDavid Brown <david.brown@hesbynett.no>
Date2015-12-29 23:13 +0100
Message-ID<n5v0di$7i3$1@dont-email.me>
In reply to#6073
On 29/12/15 21:31, Richard Heathfield wrote:
> On 26/12/15 00:54, Ramine wrote:
>>
<snip>
>
> Your article says a lot more about your programming style than it does
> about either C or C++.
>

While your post was technically correct, you are missing one critical 
detail - Ramine is a write-only bot, and never reads anything that is 
posted.  He is also almost totally ignorant about C and C++ (I haven't 
studied his Delphi code enough to guess his knowledge there), so 
criticisms of his posts are usually obvious to everyone else already. 
If you can squeeze in some tips that might be interesting to others, or 
at least an entertaining Pythonesque insult, go for it - otherwise 
replying to Ramine is fairly pointless.

[toc] | [prev] | [next] | [standalone]


#6076

FromRichard Heathfield <rjh@cpax.org.uk>
Date2015-12-29 22:19 +0000
Message-ID<n5v0p5$8s3$1@dont-email.me>
In reply to#6075
On 29/12/15 22:13, David Brown wrote:
> On 29/12/15 21:31, Richard Heathfield wrote:
>> On 26/12/15 00:54, Ramine wrote:
>>>
> <snip>
>>
>> Your article says a lot more about your programming style than it does
>> about either C or C++.
>>
>
> While your post was technically correct, you are missing one critical
> detail - Ramine is a write-only bot, and never reads anything that is
> posted.

There is a very, very, very small body of evidence to the contrary. 
Practically microscopic, in fact, but nevertheless non-zero.

> He is also almost totally ignorant about C and C++ (I haven't
> studied his Delphi code enough to guess his knowledge there), so
> criticisms of his posts are usually obvious to everyone else already. If
> you can squeeze in some tips that might be interesting to others, or at
> least an entertaining Pythonesque insult, go for it - otherwise replying
> to Ramine is fairly pointless.

In this case, the tips I thought might be interesting to others were:

1) using namespace std; is so often a bad idea that I can't actually 
think of a good use for it. (Kaz was prompted to post a scenario in 
which the 'using namespace' construct could be useful, so that's a 
positive outcome.)

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.

-- 
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

[toc] | [prev] | [next] | [standalone]


#6077

FromDavid Brown <david.brown@hesbynett.no>
Date2015-12-30 09:56 +0100
Message-ID<n6063m$ccb$1@dont-email.me>
In reply to#6076
On 29/12/15 23:19, Richard Heathfield wrote:
> On 29/12/15 22:13, David Brown wrote:
>> On 29/12/15 21:31, Richard Heathfield wrote:
>>> On 26/12/15 00:54, Ramine wrote:
>>>>
>> <snip>
>>>
>>> Your article says a lot more about your programming style than it does
>>> about either C or C++.
>>>
>>
>> While your post was technically correct, you are missing one critical
>> detail - Ramine is a write-only bot, and never reads anything that is
>> posted.
> 
> There is a very, very, very small body of evidence to the contrary.
> Practically microscopic, in fact, but nevertheless non-zero.

I had a little check on the posts from Ramine that are in my local
Thunderbird cache of this group - and I found two replies by him to
someone other than himself.  Both were to posts by you.  Over the past
year and a half, he has made 565 posts (about 10% of this group), with
/two/ of them indicating that he reads something here.

So your assessment is correct - there is a tiny, but non-zero, chance
that he will read these posts.

> 
>> He is also almost totally ignorant about C and C++ (I haven't
>> studied his Delphi code enough to guess his knowledge there), so
>> criticisms of his posts are usually obvious to everyone else already. If
>> you can squeeze in some tips that might be interesting to others, or at
>> least an entertaining Pythonesque insult, go for it - otherwise replying
>> to Ramine is fairly pointless.
> 
> In this case, the tips I thought might be interesting to others were:
> 
> 1) using namespace std; is so often a bad idea that I can't actually
> think of a good use for it. (Kaz was prompted to post a scenario in
> which the 'using namespace' construct could be useful, so that's a
> positive outcome.)

That's the one that I thought was obvious.  Some people will disagree
that it is a bad idea, but I can't imagine there are many C++ who
haven't heard this already.  And certainly it's an issue for
comp.lang.c++ rather than comp.programming.

> 
> 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.

I am always happy to see poor initial posts turned into interesting
threads - I just didn't see much scope for it here.

[toc] | [prev] | [next] | [standalone]


#6078

FromRichard Heathfield <rjh@cpax.org.uk>
Date2015-12-30 13:28 +0000
Message-ID<n60m14$lf$1@dont-email.me>
In reply to#6077
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

[toc] | [prev] | [next] | [standalone]


#6079

FromDavid Brown <david.brown@hesbynett.no>
Date2015-12-30 14:55 +0100
Message-ID<n60nkf$65m$1@dont-email.me>
In reply to#6078
On 30/12/15 14:28, Richard Heathfield wrote:
> 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.

Indeed not - this is simply a misunderstanding of a detail of the
strtoul function, which appears to be working exactly as specified.


> 
> 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!

Yes indeed, and this standard conversion is key to many of the problems
people get when mixing signed and unsigned values.  Basically, it is
only safe to do so when the signed variable is non-negative.

Of course, this in itself is just a specialist case of the difference
between "normal" mathematics and numbers in C.  Replace the first two
lines with "int16_t i = 1000000; int16_t j = 4000000;" and you'll find
that four million is apparently smaller than one million.

> 
> 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.
> 

Indeed.

In my line of work, unsigned data turns up all the time, as does the
risk of overflows of various sorts - it pays to be careful and use
appropriate casts to be exactly sure of what sizes and signedness you
have at any given time.

[toc] | [prev] | [next] | [standalone]


#6081

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2015-12-30 16:32 +0000
Message-ID<87bn977v7v.fsf@bsb.me.uk>
In reply to#6079
David Brown <david.brown@hesbynett.no> writes:

> On 30/12/15 14:28, Richard Heathfield wrote:
<snip>
>>   int i = -6;
>>   unsigned int j = 42;
>>   if(i < j)
>>   {
>>     puts("-6 is less than 42");
>>   }
<snip>
> Of course, this in itself is just a specialist case of the difference
> between "normal" mathematics and numbers in C.  Replace the first two
> lines with "int16_t i = 1000000; int16_t j = 4000000;" and you'll find
> that four million is apparently smaller than one million.

You might find that, but you also might not!  There is a conversion
which is implementation-defined (and might even raise a signal).

<snip>
-- 
Ben.

[toc] | [prev] | [next] | [standalone]


#6083

FromDavid Brown <david.brown@hesbynett.no>
Date2015-12-30 18:17 +0100
Message-ID<n613e6$jca$2@dont-email.me>
In reply to#6081
On 30/12/15 17:32, Ben Bacarisse wrote:
> David Brown <david.brown@hesbynett.no> writes:
> 
>> On 30/12/15 14:28, Richard Heathfield wrote:
> <snip>
>>>   int i = -6;
>>>   unsigned int j = 42;
>>>   if(i < j)
>>>   {
>>>     puts("-6 is less than 42");
>>>   }
> <snip>
>> Of course, this in itself is just a specialist case of the difference
>> between "normal" mathematics and numbers in C.  Replace the first two
>> lines with "int16_t i = 1000000; int16_t j = 4000000;" and you'll find
>> that four million is apparently smaller than one million.
> 
> You might find that, but you also might not!  There is a conversion
> which is implementation-defined (and might even raise a signal).
> 

Absolutely - which is why you always have to be careful with arithmetic
in C.

[toc] | [prev] | [next] | [standalone]


#6104

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2015-12-30 20:01 +0000
Message-ID<87r3i366zy.fsf@bsb.me.uk>
In reply to#6083
David Brown <david.brown@hesbynett.no> writes:

> On 30/12/15 17:32, Ben Bacarisse wrote:
>> David Brown <david.brown@hesbynett.no> writes:
>> 
>>> On 30/12/15 14:28, Richard Heathfield wrote:
>> <snip>
>>>>   int i = -6;
>>>>   unsigned int j = 42;
>>>>   if(i < j)
>>>>   {
>>>>     puts("-6 is less than 42");
>>>>   }
>> <snip>
>>> Of course, this in itself is just a specialist case of the difference
>>> between "normal" mathematics and numbers in C.  Replace the first two
>>> lines with "int16_t i = 1000000; int16_t j = 4000000;" and you'll find
>>> that four million is apparently smaller than one million.
>> 
>> You might find that, but you also might not!  There is a conversion
>> which is implementation-defined (and might even raise a signal).
>> 
>
> Absolutely - which is why you always have to be careful with arithmetic
> in C.

I'd just say "you have to be careful in C".  There's no arithmetic (in
the way I'd want to use the word) in "int16_t i = 1000000;".

-- 
Ben.

[toc] | [prev] | [next] | [standalone]


#6080

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2015-12-30 15:48 +0000
Message-ID<87h9j06ip1.fsf@bsb.me.uk>
In reply to#6078
Richard Heathfield <rjh@cpax.org.uk> writes:

> 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.

Since this is comp.programming, you should perhaps have said that mixing
signed and unsigned expressions _in C_ is often a bad sign.  It may be
in other languages too, but there are others in which it is both common
and harmless.

The points you go on to make are about problems in the way C defines the
behaviour of such mixed-type expressions -- they aren't programming
problems per se.

<snip>
-- 
Ben.

[toc] | [prev] | [next] | [standalone]


#6082

FromRichard Heathfield <rjh@cpax.org.uk>
Date2015-12-30 16:35 +0000
Message-ID<n610v9$afu$1@dont-email.me>
In reply to#6080
On 30/12/15 15:48, Ben Bacarisse wrote:

<snip>

> Since this is comp.programming, you should perhaps have said that mixing
> signed and unsigned expressions _in C_ is often a bad sign.  It may be
> in other languages too, but there are others in which it is both common
> and harmless.

Fair comment. So perhaps we could start by looking at how some other 
languages deal with unsigned integer types (or indeed whether they 
support them at all). I should say at the outset that the information I 
present below is unsatisfactorily sparse.

Ada supports signed and unsigned integer types. I couldn't find any 
rules on how mixed-sign arithmetic is done (but that doesn't mean there 
aren't any).

BASIC - tricky one. ISO/IEC 10279 defines the language, but I couldn't 
find a freely available draft.

COBOL (according to a rather strangely-formatted draft ISO Standard from 
2005) seems to support unsigned char, short, long, and even double. It 
isn't clear (from a quick scan) how COBOL deals with mixed-sign arithmetic.

D's rules are similar to C's. Particularly, if the two types are of the 
same size, then the signed type is converted to unsigned.

Eiffel supports unsigned integer types, but I found nothing in ECMA-367 
to show how they interact with signed types.

Fortran's draft standard (n3501) is rather odd. In Note 15.9 we find 
that "...Fortran does not provide direct support for unsigned kinds of 
integers", and yet in 4.4.1 Integer Type the text reads "The value of a 
signed integer zero is the same as the value of an unsigned integer 
zero", which suggests that there is /some/ kind of support for unsigned 
integers.

Go supports unsigned integer types, but a brief perusal of the spec 
didn't turn up any rules for mixed-sign arithmetic.

I ran out of time to extend this alphabetical list any further, but one 
of the first languages I thought of was PHP. I found it surprising that 
PHP doesn't appear to support an unsigned integer type (something that 
it has never before occurred to me to check, which suggests to me that I 
don't use PHP quite as often as I thought I did).

-- 
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

[toc] | [prev] | [next] | [standalone]


#6084

FromDavid Brown <david.brown@hesbynett.no>
Date2015-12-30 18:19 +0100
Message-ID<n613i4$jca$3@dont-email.me>
In reply to#6082
On 30/12/15 17:35, Richard Heathfield wrote:
> On 30/12/15 15:48, Ben Bacarisse wrote:
> 
> <snip>
> 
>> Since this is comp.programming, you should perhaps have said that mixing
>> signed and unsigned expressions _in C_ is often a bad sign.  It may be
>> in other languages too, but there are others in which it is both common
>> and harmless.
> 
> Fair comment. So perhaps we could start by looking at how some other
> languages deal with unsigned integer types (or indeed whether they
> support them at all). I should say at the outset that the information I
> present below is unsatisfactorily sparse.
> 
> Ada supports signed and unsigned integer types. I couldn't find any
> rules on how mixed-sign arithmetic is done (but that doesn't mean there
> aren't any).
> 
> BASIC - tricky one. ISO/IEC 10279 defines the language, but I couldn't
> find a freely available draft.
> 
> COBOL (according to a rather strangely-formatted draft ISO Standard from
> 2005) seems to support unsigned char, short, long, and even double. It
> isn't clear (from a quick scan) how COBOL deals with mixed-sign arithmetic.
> 
> D's rules are similar to C's. Particularly, if the two types are of the
> same size, then the signed type is converted to unsigned.
> 
> Eiffel supports unsigned integer types, but I found nothing in ECMA-367
> to show how they interact with signed types.
> 
> Fortran's draft standard (n3501) is rather odd. In Note 15.9 we find
> that "...Fortran does not provide direct support for unsigned kinds of
> integers", and yet in 4.4.1 Integer Type the text reads "The value of a
> signed integer zero is the same as the value of an unsigned integer
> zero", which suggests that there is /some/ kind of support for unsigned
> integers.
> 
> Go supports unsigned integer types, but a brief perusal of the spec
> didn't turn up any rules for mixed-sign arithmetic.
> 
> I ran out of time to extend this alphabetical list any further, but one
> of the first languages I thought of was PHP. I found it surprising that
> PHP doesn't appear to support an unsigned integer type (something that
> it has never before occurred to me to check, which suggests to me that I
> don't use PHP quite as often as I thought I did).
> 

You didn't get as far as Python, I take it.  In Python, the integer
types just get as big as you need (until you run out of time or memory).
 So to a large extent you can assume your integers really are
mathematical integers, and add them as much as you want.  (So "unsigned"
integers don't really exist.)

[toc] | [prev] | [next] | [standalone]


#6086

FromRichard Heathfield <rjh@cpax.org.uk>
Date2015-12-30 17:39 +0000
Message-ID<n614nj$p08$1@dont-email.me>
In reply to#6084
On 30/12/15 17:19, David Brown wrote:

<snip>

> You didn't get as far as Python, I take it.

No. I would in any case have chosen PHP for my 'P' language, but from 
what you say below it seems that Python would have been the more 
interesting choice.

> In Python, the integer
> types just get as big as you need (until you run out of time or memory).
>   So to a large extent you can assume your integers really are
> mathematical integers, and add them as much as you want.  (So "unsigned"
> integers don't really exist.)

What if I wanted to construct a candidate for a large prime? The usual 
way to do this is to pick a number of bits, set the top and bottom bits, 
and then arbitrarily assign other bits (either setting or clearing them, 
as dictated by some entropy source). Then one applies Miller-Rabin a few 
times, and adds 2 if any of the tests fail. Traditionally one uses an 
array of unsigned char for this, but if you don't /have/ unsigned char, 
or indeed any unsigned type, presumably you could still do this with 
code such as:

candidate = 1 << (bitcount - 1);
candidate |= 1;
for i = 1 to bitcount - 2
   candidate |= getrandomnumber(0,1) << i;

?

(I realise I'm moving away from signed/unsigned here!)

-- 
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

[toc] | [prev] | [next] | [standalone]


#6113

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2015-12-30 20:26 +0000
Message-ID<87lh8b65tq.fsf@bsb.me.uk>
In reply to#6086
Richard Heathfield <rjh@cpax.org.uk> writes:

> On 30/12/15 17:19, David Brown wrote:
>
> <snip>
>
>> You didn't get as far as Python, I take it.
>
> No. I would in any case have chosen PHP for my 'P' language, but from
> what you say below it seems that Python would have been the more
> interesting choice.
>
>> In Python, the integer
>> types just get as big as you need (until you run out of time or memory).
>>   So to a large extent you can assume your integers really are
>> mathematical integers, and add them as much as you want.  (So "unsigned"
>> integers don't really exist.)
>
> What if I wanted to construct a candidate for a large prime? The usual
> way to do this is to pick a number of bits, set the top and bottom
> bits, and then arbitrarily assign other bits (either setting or
> clearing them, as dictated by some entropy source). Then one applies
> Miller-Rabin a few times, and adds 2 if any of the tests
> fail. Traditionally one uses an array of unsigned char for this, but
> if you don't /have/ unsigned char, or indeed any unsigned type,
> presumably you could still do this with code such as:
>
> candidate = 1 << (bitcount - 1);
> candidate |= 1;
> for i = 1 to bitcount - 2
>   candidate |= getrandomnumber(0,1) << i;
>
> ?

Yes (though I'd probably set the bits in larger chucks).  In actual
Python:

    candidate = 1 << (bitcount - 1);
    candidate |= 1;
    for i in range(1, bitcount - 2):
        candidate |= random.randint(0,1) << i;

> (I realise I'm moving away from signed/unsigned here!)

-- 
Ben.

[toc] | [prev] | [next] | [standalone]


#6085

From"Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de>
Date2015-12-30 18:32 +0100
Message-ID<n614fp$q6t$1@speranza.aioe.org>
In reply to#6082
On 2015-12-30 17:35, Richard Heathfield wrote:

> Ada supports signed and unsigned integer types.

Not quite. Ada has integer types (with overflow exceptions) and modular 
types (ring N arithmetic).

Modular types with power of two modulo is what people mean when they 
talk about "unsigned integer" types. E.g.

    type Unsigned_16 is mod 2**16;

> I couldn't find any
> rules on how mixed-sign arithmetic is done (but that doesn't mean there
> aren't any).

There is no such rules. Since Ada is a strongly typed language, you just 
cannot mix types. You need an explicit type conversion to the type of 
another operand in order to use its arithmetical operation. (You can 
define mixed types operations of your own, if you wish)


-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de

[toc] | [prev] | [next] | [standalone]


#6102

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2015-12-30 19:55 +0000
Message-ID<87wprv679l.fsf@bsb.me.uk>
In reply to#6082
Richard Heathfield <rjh@cpax.org.uk> writes:

> On 30/12/15 15:48, Ben Bacarisse wrote:
>
> <snip>
>
>> Since this is comp.programming, you should perhaps have said that mixing
>> signed and unsigned expressions _in C_ is often a bad sign.  It may be
>> in other languages too, but there are others in which it is both common
>> and harmless.
>
> Fair comment. So perhaps we could start by looking at how some other
> languages deal with unsigned integer types (or indeed whether they
> support them at all). I should say at the outset that the information
> I present below is unsatisfactorily sparse.
>
> Ada supports signed and unsigned integer types. I couldn't find any
> rules on how mixed-sign arithmetic is done (but that doesn't mean
> there aren't any).

It won't surprise you to know that there are some.  Exactly what they
are depends of what you mean by unsigned types in Ada.  Do you mean the
standard type Natural, one of the modulo types, or something else?  Ada
is type safe, and tries to be mathematically "safe" as well, hence your
i < j would be either false (if j is 'natural') or a type error if it's
a modulo type.

> BASIC - tricky one. ISO/IEC 10279 defines the language, but I couldn't
> find a freely available draft.

There's an ISO standard BASIC?  Well, gosub 100 and call me structured.
I don't think it has integers, let alone unsigned ones, but I could not
find anything definitive.

> COBOL (according to a rather strangely-formatted draft ISO Standard
> from 2005) seems to support unsigned char, short, long, and even
> double. It isn't clear (from a quick scan) how COBOL deals with
> mixed-sign arithmetic.

One of the few languages I don't care about.

A more interesting letter 'C' for me (and probably for you too) would be
Cryptol.  It has no signed arithmetic at all making -1 < 1 false.

> D's rules are similar to C's. Particularly, if the two types are of
> the same size, then the signed type is converted to unsigned.

Not surprising, but a shame that it did not try to fix this.

> Eiffel supports unsigned integer types, but I found nothing in
> ECMA-367 to show how they interact with signed types.

Pass, but I'd put a substantial bet on it being more like Ada than C.

> Fortran's draft standard (n3501) is rather odd. In Note 15.9 we find
> that "...Fortran does not provide direct support for unsigned kinds of
> integers", and yet in 4.4.1 Integer Type the text reads "The value of
> a signed integer zero is the same as the value of an unsigned integer
> zero", which suggests that there is /some/ kind of support for
> unsigned integers.

I _think_ that's talking about the textual representation.  There's
nothing analogous to C's unsigned in Fortran (or there wasn't the last
time I looked).

> Go supports unsigned integer types, but a brief perusal of the spec
> didn't turn up any rules for mixed-sign arithmetic.

The comparison is a type error in Go (and arithmetic would be too).
Relational operators require "assignable types" and arithmetic requires
identical types (with an exception for shifts).

> I ran out of time to extend this alphabetical list any further,

And just before my favourite -- Haskell.

> but
> one of the first languages I thought of was PHP. I found it surprising
> that PHP doesn't appear to support an unsigned integer type (something
> that it has never before occurred to me to check, which suggests to me
> that I don't use PHP quite as often as I thought I did).

-- 
Ben.

[toc] | [prev] | [next] | [standalone]


#6111

FromRichard Heathfield <rjh@cpax.org.uk>
Date2015-12-30 20:15 +0000
Message-ID<n61ds0$sn0$1@dont-email.me>
In reply to#6102
On 30/12/15 19:55, Ben Bacarisse wrote:
> Richard Heathfield <rjh@cpax.org.uk> writes:
>
>> BASIC - tricky one. ISO/IEC 10279 defines the language, but I couldn't
>> find a freely available draft.
>
> There's an ISO standard BASIC?  Well, gosub 100 and call me structured.
> I don't think it has integers, let alone unsigned ones, but I could not
> find anything definitive.

There is, you're structured, I'm fairly sure it does, I doubt whether it 
does, and neither could I (in that order).

>
> A more interesting letter 'C' for me (and probably for you too) would be
> Cryptol.  It has no signed arithmetic at all making -1 < 1 false.

I'll take a look when I get five minutes.

>
>> I ran out of time to extend this alphabetical list any further,
>
> And just before my favourite -- Haskell.

Yep, I was going to choose Haskell. But since it's your favourite, how 
does Haskell deal with signedness/unsignedness?

-- 
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

[toc] | [prev] | [next] | [standalone]


#6120

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2015-12-30 22:00 +0000
Message-ID<87a8or61he.fsf@bsb.me.uk>
In reply to#6111
Richard Heathfield <rjh@cpax.org.uk> writes:

> On 30/12/15 19:55, Ben Bacarisse wrote:
>> Richard Heathfield <rjh@cpax.org.uk> writes:
<snip>
>>> I ran out of time to extend this alphabetical list any further,
>>
>> And just before my favourite -- Haskell.
>
> Yep, I was going to choose Haskell. But since it's your favourite, how
> does Haskell deal with signedness/unsignedness?

Haskell has no unsigned types in the core language, so in the normal
course of programming the question does not come up.

But some unsigned, fixed-width integer types have been added to the
standard library.  These use modular arithmetic and are probably there
for compatibility with other languages (I've never used them and I'm not
sure what they are for).

Fundamentally, mixed-type arithmetic is a type error in Haskell because
all Haskell arithmetic functions require the arguments to be of the same
type.  But it's not quite that simple, because Haskell can infer the
types of functions (like + and <) from the types of the arguments, and
it uses a system of type classes (whether a type is ordered, or numeric,
or bounded and so on) to determine what you can do with them.  As a
result, the behaviour depends on how the unsigned types are implemented.

The upshot is that, for the now standard type Data.Word, you can get
this situation which looks similar to C (this is an interactive ghci
session):

  Prelude Data.Word> let i = -6; j = 42::Word
  Prelude Data.Word> i < j
  False

This is because all Haskell knows about i is that it is numeric:

  Prelude Data.Word> :t i
  i :: Num a => a

If we are explicit about the types, you get a type error:

  Prelude Data.Word> let i = -6::Integer; j = 42::Word
  Prelude Data.Word> i < j
   
  <interactive>:6:5:
      Couldn't match expected type ‘Integer’ with actual type ‘Word’
      In the second argument of ‘(<)’, namely ‘j’
      In the expression: i < j

-- 
Ben.

[toc] | [prev] | [next] | [standalone]


#6116

FromIan Collins <ian-news@hotmail.com>
Date2015-12-31 10:16 +1300
Message-ID<deivu4FsqnhU7@mid.individual.net>
In reply to#6076
Richard Heathfield wrote:
> On 29/12/15 22:13, David Brown wrote:
>> On 29/12/15 21:31, Richard Heathfield wrote:
>>> On 26/12/15 00:54, Ramine wrote:
>>>>
>> <snip>
>>>
>>> Your article says a lot more about your programming style than it does
>>> about either C or C++.
>>>
>>
>> While your post was technically correct, you are missing one critical
>> detail - Ramine is a write-only bot, and never reads anything that is
>> posted.
>
> There is a very, very, very small body of evidence to the contrary.
> Practically microscopic, in fact, but nevertheless non-zero.

So microscopic that I'm sure my host (N.I.N) filters out his posts as 
spam.  So now my "ignore thread" filters can't block replies to its posts!

-- 
Ian Collins

[toc] | [prev] | [standalone]


Back to top | Article view | comp.programming


csiph-web