Why C++ is vastly superior to C

M

MikeP

I'm not saying C++ is a "simple" language. However, it is, by this
definition, *simpler* than C.

I was just noting the obvious: that "simplicity" requires more context to
be meaningful and that it is subjective. I only posted because you used
such absolute wording ("simplicity means...") when it can mean different
things to different people.

There are, of course two problems with that:

1) It's not standard, and hence if you need to do a project somewhere
where you don't have your toolset, you'll have to start from scratch.
Also, it doesn't help others to understand your code if they haven't
used the same toolset.

That's only a problem for that scenario, not a problem in general.
2) Most generic tools you could write in C are harder and less safe to
use (compared to most other languages, including C++). Typically the
more generic the library, the less efficiency, type safety and
usability.

Agreed. But that is just another day in the life of a C programmer, and
that is the way it used to be done way back in the 18th century. :)
If you use your own tool instead of a standard tool even in
situations where the standard tool would be perfectly suited, that's
not very smart.

Opinions vary. I note that you are an "in the paint" kind of guy:
"standards this... standards that". To each their own is what I say.
 
M

MikeP

Rui said:
If you really wish to know that then all you have to do is put in the
leg work and check it for yourself. Why did you failed to do that
and instead opted to simply whine?

Look up the word 'rhetorical'.
You can whine about anything you wish, really. The fact is, I've
criticized an attempt at evaluating the market share of a set of
languages and, to complement that, I've provided a more objective,
quantitative way to evaluate that.

I noted that the attempt was a lame one and posted a few RHETORICAL
questions to get you to think about why I said it was a lame attempt.
You, on the other hand, threw a
set of questions to which, as a demonstration on how relevant you
think they are, you don't even want to get the answer to and, based
on that silly permisse, went forward to bitch about how "lame" this
source of data was.

I didn't suggest that the source of the data was lame, but rather that
the poster's suggestion that what he posted was somehow meaningful and
indicative as it stands is simply not true.
So, if you really want to discuss how "lame" a source of data is then
at the very least provide any data which you believe is better than
this. Until that, tone down your "lame" posts.

A bit sensitive are ya?
 
M

MikeP

Joshua said:
I laughed when I saw your acronym. I assume that was just made up on
the spot.

I've used it in source code before to document stuff. It's a relevant
issue so it probably needs an acronym.
The point is, C++ programmers can choose between "The C way"(tm) and
templates. C people are stuck with one side of the tradeoff. I don't
think you're disagreeing, but I'm just being contrarian to your
contrarian.

I was just pointing out that nothing is free. Usually in coding there is
a space-time tradeoff and that's exactly what you get with templates vs.
void*.
 
M

MikeP

Nobody said:
C exceptions (i.e. longjmp) also require it.


I suppose it depends upon whether legibility is important/necessary or
merely a convenience. The contortions required to get by without it
can be pretty ugly. Similarly, one could ask whether high-level
languages are important/necessary, or merely a convenience.

I think it depends on how creative one is.
 
M

MikeP

Joshua said:
That's a matter of opinion.

The first thing that Bjarne Stroustrup added to C to make C++ was
destructors, more or less. In his own words in this forum, it predated
all the other cool things, like templates, virtual, exceptions, by
years. I agree with Bjarne that the thing I miss the most when I'm
forced to do C, or maintain C-like C++ code, is destructors.

The utility of destructors is not mere syntactic sugar like a ranged-
based for loop ala Java and C++0x or even the virtual keyword.
Implicit calling of functions when objects leave scope is incredibly
"powerful" and useful. It greatly reduces a whole class of programming
errors. It does this IMHO in two main ways. First it helps the
programmer not forget to add a free-resource call to a deinit call
(now also usually a destructor), and helps the programmer not forget a
free-resource call (now also usually a destructor) on an exit path in
a function.

Second, it helps foster a certain kind of programming paradigm where
the coder ensures that all resources have an owner at all times. Most
of the time, that is except for the occasional no-throw block or no-
throw operation which transfers ownership or allocates a resource, you
can unwind the stack at any time and you will not leak resources -
required with exceptions, but still useful otherwise. When all
resources have a clearly identified owner (and thus destruction
condition), and the ownership graph in large part has all of its roots
in stack objects, leaks become much rarer, especially with the
idiomatic usage.

RAII is an idiom that is built upon the mechanisms that allow
user-defined types to behave somewhat like built-in types. A trace class
can use the same mechanisms but there are no resources to speak of in
that scenario. RAII has become such a clouding concept to the
underpinnings. It seems like there is some terminology conspicuously
absent in between the mechanisms and the high level idiom RAII (and of
course the trace scenario is a sibling implementation of the pattern that
RAII is based on).
 
M

MikeP

Juha said:
I don't understand where this notion is coming from.

Even if exceptions were disabled (in many compilers you can disable
them so that they will never be thrown) it would still be a nightmare
to develop a large project without RAII.

But not impossible. And creativity counts. Do/undo and keep functions
short (the C way) and then you're out of the realm of "nightmare". (Not
that I'm suggesting one do it that way).
I would say the opposite of you: RAII is essential. The fact that it
allows making code exception-safe is a nice side-effect, but not the
main point.

The scoped lifetime of classes on the stack is nifty, yes. I think the
RAII idiom necessarily brings in the exception stuff though. It's the
best way to do it, but not the only way (unless you turn on the exception
switch on the compiler). Constructors and operators need exceptions,
exceptions necessitate RAII... it's a chain reaction of which there are
at least a few of in the design of C++. It's a steep learning curve at
first (and maybe even longer than just at first). Once one knows the
idioms though, it's not too bad.

I'm rambling, I better go to bed.
 
M

MikeP

Rui said:
I don't believe that the differences between C++ and C are equivalent
to the differences between a house with indoor plumbing and
electricity and a cave. I see it more as the difference between a
house fully stocked with a hefty set of conveniences and features
such as home automation, HVAC and even HAL from 2001: A Space
Odyssey, and the exact same house with barely any furniture and
stripped of any of those bells and wistles. Both are good houses,
you can live confortably in any of those but in some cases you don't
have those gadgets helping you/constantly getting on your way.

OK, the caves would probably be assembly language. C is more like a
fishing shack where you have to bring wood in from outside to burn in
that big iron thing in the middle of the room to get warm and C++ more
like a nice "modern" (1970-ish) house (which, of course, started life as
a fishing shack but got remodeled and added-on to over the years as
people started to retire from their city jobs and moved to their place in
the country), but not as extravagant as you say. You are talking about D
(!). ;-)
 
S

Stefan Ram

MikeP said:
Keith said:
[...] I would say that
the C++ automatic constructor/destructor paradigm (which was a C++
innovation as far as I know?) is also extremely valuable.
Innovation? Looks like a quite nice and convenient side-effect.

Anyways, that's the history of template-based
metaprogramming (which is a side-effect of templates and
was shown by Erwin Unruh in 1994).
 
S

Stefan Ram

MikeP said:
RAII has become such a clouding concept to the underpinnings.

Why is it »clouding«?
It seems like there is some terminology conspicuously absent
in between the mechanisms and the high level idiom RAII

If terminology is missing for something that already exists,
the terminology can be introduced. Would you mind to suggest
some of this terminology?
 
B

Balog Pal

MikeP said:
Type "template code bloat" or "C++ template code bloat" into your favorite
internet search engine and you'll get a long listing.

Type in bullshit at the same place to get an even longer list... Care to
explain your own assertion, especially what bloat is created compared to
what alternative executing the same task?

Or you're just creating flood to have more posts i this thread than the rest
together?
 
D

Dombo

Op 21-May-11 16:08, MikeP schreef:
But not impossible. And creativity counts. Do/undo and keep functions
short (the C way) and then you're out of the realm of "nightmare". (Not
that I'm suggesting one do it that way).


The scoped lifetime of classes on the stack is nifty, yes. I think the
RAII idiom necessarily brings in the exception stuff though. It's the
best way to do it, but not the only way (unless you turn on the exception
switch on the compiler). Constructors and operators need exceptions,
exceptions necessitate RAII... it's a chain reaction of which there are
at least a few of in the design of C++.

Several C++ compilers I have used in the early nineties didn't support
exceptions at all, yet they did support constructors and destructors.
In those days classes often had an initialize method or a method to
check if the object was successfully constructed; not particularly
elegant but at the end of the day it did get the job done.

There certainly is a strong synergy between exceptions and RAII in C++,
the C++ language would have been a lot worse without one or the other.
But without exceptions RAII would be still useful, whereas exceptions
would be useless in C++ without RAII (unless something like a 'finally'
clause were added to the language).
 
N

Nobody

The point is that C advocates try to ride on the concept of language
simplicity. With other languages simplicity means not only that the
language specification is relatively short, but also that writing
programs is simple and straightforward (because, among other things,
the programmer is not burdened by memory management and other similar
issues). The simplicity of the language directly correlates to how much
you have to write in order to implement a given task, and how much of
what you write is directly related to the task itself (rather than to
ancillary things like memory management). Also, how easy it is to
understand the code.

For the kind of task that C was designed for, and is best suited for,
there's a strong correlation between simplicity of implementation and
simplicity of usage.

When you need to know and/or control the details of what's going under the
hood, having the implementation do too much for you can make it harder to
use rather than easier. E.g. if you're likely to adjust your code based
upon the resulting assembly language, having a fairly direct
correspondence between source code and assembler is an advantage.

In terms of understanding the code, the ability of C++ to "hide" code in
constructors and overloaded operators can be seen as an impediment to
legibility. The C++ perspective is that you don't need to know the
details; you just trust that the implementation behaves correctly. In
situations where C is the correct choice, the details often matter.
 
K

Keith H Duggar

Keith said:
[...] I would say that
the C++ automatic constructor/destructor paradigm (which was a C++
innovation as far as I know?) is also extremely valuable.

Innovation? Looks like a quite nice and convenient side-effect.

Side-effect of what? Which languages do you know of that
had automatic deterministic destructors prior to C++?

KHD
 
J

Juha Nieminen

Nobody said:
In terms of understanding the code, the ability of C++ to "hide" code in
constructors and overloaded operators can be seen as an impediment to
legibility. The C++ perspective is that you don't need to know the
details; you just trust that the implementation behaves correctly. In
situations where C is the correct choice, the details often matter.

That argument makes no sense. Constructors and overloaded operators
are just functions. C supports functions as well. Functions whose source
code might not be available at all. I don't understand your argument.
 
D

Dombo

Op 21-May-11 20:43, Juha Nieminen schreef:
That argument makes no sense. Constructors and overloaded operators
are just functions. C supports functions as well. Functions whose source
code might not be available at all. I don't understand your argument.

The difference is that C if you want some thing to happen you must
explicitly write code for it; what you see is what you get. In C++ lots
of things can happen because of an innocently looking statement or even
when there is no code at all (destructors); you may very well get more
than that you see.
 
B

Balog Pal

Dombo said:
The difference is that C if you want some thing to happen you must
explicitly write code for it; what you see is what you get. In C++ lots of
things can happen because of an innocently looking statement or even when
there is no code at all (destructors); you may very well get more than
that you see.

Is there any real difference? C was created as a "portable assembler". You
lost the "what you see" attribute right with that step.

By design certainly, that was the point -- you write code using abstract
types like int, short, pointers, "arrays", and the approppriate assembly
code is generated for the platform.

Can you tell what machine instructions you will get from a C source? For
some level, yes: if you know the semantics.

But the very same is true for C++.
 
K

Kai-Uwe Bux

Balog said:
Is there any real difference?

I think it does make a real difference. Well, I don't know C; but I see a
difference between a language where you have to be explicit about the things
that happen at a particular point of the control flow (from the above, C is
supposedly such a language) and a language where many things are left
implicit (i.e., what happens at this point of flow has been specified at
some remote location in the code).

In C++, destructors and exceptions are the two things that carry a load of
implicitness with them. That it makes a real difference is illustrated by
the need of people getting used to it. If it was "just the same", old habits
should carry over and work just fine. The difficulty of learning to aquire
the habit of writing code that fares well in the presence of possible
exceptions goes to show that the difference is real.
C was created as a "portable assembler".
You lost the "what you see" attribute right with that step.

By design certainly, that was the point -- you write code using abstract
types like int, short, pointers, "arrays", and the approppriate assembly
code is generated for the platform.

Can you tell what machine instructions you will get from a C source? For
some level, yes: if you know the semantics.

But the very same is true for C++.

True, but the claimed difference was not that you can see the assembly code
through the C code. The difference was that you have to be explicit about
what should happen: if you don't issue the command here (at this point in
code), it won't happen now (when control flow passes through this point in
code). I don't know whether that description holds for C, but surely it does
not for C++.


Best,

Kai-Uwe Bux

p.s.: Note that I am not saying that being explicit is better.
 
D

Dombo

Op 21-May-11 21:48, Balog Pal schreef:
Is there any real difference? C was created as a "portable assembler".
You lost the "what you see" attribute right with that step.

I never looked seriously at C99 but the last time I looked at C it
didn't have destructors, exceptions, templates or other constructs that
can generate surprising amounts of code if one is not careful.
By design certainly, that was the point -- you write code using abstract
types like int, short, pointers, "arrays", and the approppriate assembly
code is generated for the platform.

Can you tell what machine instructions you will get from a C source? For
some level, yes: if you know the semantics.

But the very same is true for C++.

In the strict sense that can be said for just about any language, but
for some programming languages it is easier to predict what code will
generated than others. There are many shades of gray between black and
white.

The point "Nobody" was making is that C being such a low level language
the translation from source code to assembly is relatively
straightforward, so it is easier for a programmer to predict what kind
of code and how much code the compiler will produce by just looking at
the source code. In many cases this is a matter of no concern, but in
small embedded systems where every cycle counts and the amount memory is
expressed in Kilobytes or less rather than Mega- or Gigabytes you don't
want to have too much between you and the bare metal. In some cases C
might be the right compromise between assembly and C++.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,057
Latest member
KetoBeezACVGummies

Latest Threads

Top