[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.programming

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

Ramine

12/26/2015 12:54:00 AM


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;

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

unsigned int result1 = u + i;
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 , because this types of
conversion can cause bugs and errors of logic , so i think we must
forbid C and C++ on realtime critical systems... and i have read on
internet that C and C++ are strongly typed languages, how can you
say that ! ingnoring the simple fact that an implicit conversion
in C++ and C takes place between a signed int type and an unsigned int
type for example, so that makes C and C++ problematic and not suited for
realtime critical systems and such, ADA and Delphi and FreePascal are in
fact strongly typed and does not authorize this type of conversion.



Thank you,
Amine Moulay Ramdane.











22 Answers

Öö Tiib

12/26/2015 1:58:00 PM

0

On Friday, 25 December 2015 23:53:07 UTC+2, Ramine wrote:
>
> In this example, C++ and C will convert i from a signed int type to
> unsigned int type but this is not good , because this types of
> conversion can cause bugs and errors of logic , so i think we must
> forbid C and C++ on realtime critical systems... and i have read on
> internet that C and C++ are strongly typed languages, how can you
> say that ! ingnoring the simple fact that an implicit conversion
> in C++ and C takes place between a signed int type and an unsigned int
> type for example, so that makes C and C++ problematic and not suited for
> realtime critical systems and such, ADA and Delphi and FreePascal are in
> fact strongly typed and does not authorize this type of conversion.
>

Software that is written by people who have difficulties with logic and
so use trial and error to write their code may work.
It is exceedingly difficult to use C or C++ with that method because
those languages are permissive. The languages assume that programmer
does exactly know what he is doing.

>
>
> Thank you,
> Amine Moulay Ramdane.

Kaz Kylheku

12/26/2015 5:20:00 PM

0

On 2015-12-26, �ö Tiib <ootiib@hot.ee> wrote:
> On Friday, 25 December 2015 23:53:07 UTC+2, Ramine wrote:
>>
>> In this example, C++ and C will convert i from a signed int type to
>> unsigned int type but this is not good , because this types of
>> conversion can cause bugs and errors of logic , so i think we must
>> forbid C and C++ on realtime critical systems... and i have read on
>> internet that C and C++ are strongly typed languages, how can you
>> say that ! ingnoring the simple fact that an implicit conversion
>> in C++ and C takes place between a signed int type and an unsigned int
>> type for example, so that makes C and C++ problematic and not suited for
>> realtime critical systems and such, ADA and Delphi and FreePascal are in
>> fact strongly typed and does not authorize this type of conversion.
>>
>
> Software that is written by people who have difficulties with logic and
> so use trial and error to write their code may work.
> It is exceedingly difficult to use C or C++ with that method because
> those languages are permissive. The languages assume that programmer
> does exactly know what he is doing.

Not allowing an implicit conversion between integer and floating is
"stupidly typed". Forcing explicit conversions for this into programs
adds so much clutter that it's not worth it.

Many languages have this conversion freedom, including ones that do not
have C's reputation for making it difficult to develop reliable
programs.

Python:

>>> 1.0 + 2
3.0
>>>

Common Lisp (using CLISP implementation):

[1]> (+ 1.0 2)
3.0

Ruby:

> 1.0 + 2
=> 3.0

One source of bugs is verbose clutter, where they can hide.

Richard Heathfield

12/29/2015 8:31:00 PM

0

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

Kaz Kylheku

12/29/2015 9:20:00 PM

0

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.

David Brown

12/29/2015 10:14:00 PM

0

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.


Richard Heathfield

12/29/2015 10:20:00 PM

0

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

David Brown

12/30/2015 8:57:00 AM

0

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.


Richard Heathfield

12/30/2015 1:29:00 PM

0

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

David Brown

12/30/2015 1:56:00 PM

0

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.


Ben Bacarisse

12/30/2015 3:49:00 PM

0

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.