Why C++ is vastly superior to C

I

Ian Collins

It's quite difficult to kludge any kind of generic data containers in C
(which is probably the reason why the standard C library does not offer
any such containers). You could achieve something similar with preprocessor
macros, but it would be quite limited, and definitely less safe (in big
part because of the lack of RAII, constructors, destructors, etc).

I think you are spot on with why C lacks standard containers. But it
does have a limited set of generic algorithms.
You could perhaps make some more or less generic containers for basic
types and structs which only contain basic types (but not pointers) with
preprocessor macros, but immediately when you need more resource management
than that (such as a struct that as pointers pointing to dynamically
allocated memory or other such resources) it becomes complicated. For that
same reason it's complicated to make the containers nested. (Assigning
a container object would not be the same as assigning a basic type.)

If you want an idea how complicated it is, have a look at the C
containers library Jacob Navia has been developing
(http://code.google.com/p/ccl/).
It's so much simpler with C++ templates. Just write any amount of
nested containers you want, no problem.

std::deque<std::list<std::vector<std::set<std::string> > > > container;

I'm not saying it's not a lot easier to do generic containers or
algorithms with templates. I'm saying it's impossible to do RAII in C.

I've often been asked by teams I've managed or coached why they should
look at using C++ rather than C and my response normally something along
the lines of "what's an automatic, simple means of preventing resource
leaks worth to you?" Then we get onto the other stuff! One (DSP) team
was happy just to use C++ as "C with RAII (and function overloading)".
 
L

Lynn McGuire

I think you are spot on with why C lacks standard containers. But it does have a limited set of generic algorithms.


If you want an idea how complicated it is, have a look at the C containers library Jacob Navia has been developing
(http://code.google.com/p/ccl/).


I'm not saying it's not a lot easier to do generic containers or algorithms with templates. I'm saying it's impossible to do RAII in C.

I've often been asked by teams I've managed or coached why they should look at using C++ rather than C and my response normally
something along the lines of "what's an automatic, simple means of preventing resource leaks worth to you?" Then we get onto the
other stuff! One (DSP) team was happy just to use C++ as "C with RAII (and function overloading)".

True. And better code syntax error detection than C ever
thought of.

Lynn
 
S

Stefan Ram

Joshua Maurice said:
Take C's sort. The comparator function is a function pointer,
and the last I heard is that most compilers simply will not
expand that inline, as opposed to C++ various sort functions
which can be expanded inline.

According to

http://shootout.alioth.debian.org/u32/which-programming-languages-are-fastest.php

C++ is not much faster than C (the median value actually is
a little bit slower than C if I understand the table right),
and according to

http://www.tiobe.com/content/paperinfo/tpci/images/tpci_trends.png

, C++ has lost half of its »market share« in relation to C
since 2003.

However, C++ is much more complicated and large than C.
Programmers have to learn exception-safe programming, the
rule of the three, references, König-lookup, soon rvalue
references ... up to the point where, AFAIK, the recent
draft of the language specification has more than 1000
pages, not including the C spec it is based one.

When the market share continues to decline, C++ will become
a legacy language of the 90s.
 
S

Stefan Ram

Ian Collins said:
I normally just use RAII as the reason. Everything else else can be
kludged in C, but not RAII.

RAII helps to release resources even in the case of exceptions.
But C does not have exceptions. So RAII is not needed for this.

RAII helps to do one thing »alloc()« at block entry and another
thing »release()« at block exit. This can be done in C using:

if( a = alloc() ){ rest(); release( a ); }.
 
I

Ian Collins

According to

http://shootout.alioth.debian.org/u32/which-programming-languages-are-fastest.php

C++ is not much faster than C (the median value actually is
a little bit slower than C if I understand the table right),
and according to

That, as ever, depends on what you are doing.
However, C++ is much more complicated and large than C.
Programmers have to learn exception-safe programming, the
rule of the three, references, König-lookup, soon rvalue
references ...

No, they don't. They may have to if they are supporting legacy code
that uses every feature under the sun (which tends to be written by
novices keen to use them!). For new projects, they can choose a subset
they are happy with.
up to the point where, AFAIK, the recent
draft of the language specification has more than 1000
pages, not including the C spec it is based one.

The complexity of any given problem is constant. Whether that
complexity is hidden in a language or exposed user code is a choice.
Most of the new features will remove complexity from user code.
 
I

Ian Collins

RAII helps to release resources even in the case of exceptions.
But C does not have exceptions. So RAII is not needed for this.

It also enables early return (whether that's considered good practice is
another debate!), removing the need for those awful gotos so often seen
in C code.
RAII helps to do one thing »alloc()« at block entry and another
thing »release()« at block exit. This can be done in C using:

if( a = alloc() ){ rest(); release( a ); }.

It can't be done automatically in C.
 
S

Stefan Ram

Ian Collins said:
That, as ever, depends on what you are doing.

I agree. Still a benchmark using several different
programs gives at least a vague hint.
No, they don't. They may have to if they are supporting legacy code

There are more »maintainence programmer hours«
(as I recently read, but - sorry - I forget where)
than there are »build-from-scratch programmer hours«
paid in the world today.

However, as many programmers only use a subset of C++'s features,
often that legacy code will indeed not use every feature.
But a programmer might not know /which/ features his next
maintainance project has chosen to use, so he might feel
the need to be prepared for every possible features.

One needs to write exception-safe code even if one never
»uses« (that is, throws or catches) exceptions, because called
library functions might throw exception. One might never define
overloaded function names, but still needs to know, what's
wrong with »( ::std::cos( 0 ))«.
 
J

Joshua Maurice

  According to

http://shootout.alioth.debian.org/u32/which-programming-languages-are...

  C++ is not much faster than C (the median value actually is
  a little bit slower than C if I understand the table right),

I would have assumed that we both knew:

1- Such measures are less than reliable. Specifically, to take a quote
from that link "No. Which programming language implementations have
the fastest benchmark programs?".

2- I did not make any claim that programs written in C++ are faster
than programs written in C. I made the claim that in C++ you can have
reusable code, such as containers, without overhead, and you cannot in
C (short of evil preprocessor hackery).
  and according to

http://www.tiobe.com/content/paperinfo/tpci/images/tpci_trends.png

  , C++ has lost half of its market share in relation to C
  since 2003.

  However, C++ is much more complicated and large than C.
  Programmers have to learn exception-safe programming, the
  rule of the three, references, K nig-lookup, soon rvalue
  references ... up to the point where, AFAIK, the recent
  draft of the language specification has more than 1000
  pages, not including the C spec it is based one.

  When the market share continues to decline, C++ will become
  a legacy language of the 90s.

That is an interesting proposition. However, I want to be clear that
in this thread I have not made any sort of claim that programming in C+
+ is faster, better, results in faster code, in better code, or
whatever.

PS: I may hold those beliefs, but I haven't made those claims in this
thread. :)
 
I

Ian Collins

"Resource Acquisition is Initialization". The primary benefit from RAII is
ordering resource initializations so that you don't end up with an
innumerable number of failure combinations, and limiting shared ownership of
resources, preferable in a strongly hierarchical arrangement. It's not in
automatic destruction of automatic storage objects, which is comparatively
more useful in C++ than C because in C++ the exit from a routine could be
involutary given exceptions.

The presence or lack of exceptions does indeed play a big part in the
importance of RAII in C++. But even in their absence, automatic clean
up does lead to cleaner code and more importantly, greater code reuse.
By extending RAII into smart pointers, another class of dynamic resource
management is abstracted away from the user - ownership.
Proper ordering of resource mangement in C also gets you the majority of
these benefits, a result not of language features but of good programming
habits. Comparing poor resource management in C with good resource
management in C++ is comparing apples to oranges. If programmers were so
inept at tracking memory anyhow, they'd be best in a GCd environment. If
they feel the impulse to allocate dynamic strings randomly where ever it
suits them, then they're begging for leaks, and really should be using a GCd
language, whether in C or C++. If they properly order allocation of these
resources, then the gap between C and C++ becomes quite small; maybe not
small enough, but perhaps for other considerations to move to the forefront.

Yes good practice can also handle these issues, but at the cost of more
code, more reviews and ultimately, more chance of a hapless maintenance
programmer inadvertently messing the whole thin up.

Don't forget memory isn't the only dynamic resource that has to be
managed, so GC only goes part of the way. Which is one reason most
(all?) GC'd languages end up with some form of finalise construct where
all the code that sits under a goto in C ends up!
[I'll refrain from commenting on the obscene nested containers example as
I'm sure it made you cringe as well.]

It did!
 
J

Joshua Maurice

[I'll refrain from commenting on the obscene nested containers example as
I'm sure it made you cringe as well.]

It did!

It's not so obscene if you de-trivialize it - that is make it look
like proper code. Imagine a class that you want as a value of a
std::map, and that value type itself contains a std::vector. Surely
this is a rather common situation. It is for me at least. I wouldn't
write such a typedef. Instead, I would use named types to make clear
the abstractions in use. Ex:

#include <map>
#include <string>
#include <vector>
using namespace std;
struct Foo
{ string something;
string something_else;
vector<int> and_something_else;
};
int main()
{ map<string, Foo> x;
}
 
R

Rui Maciel

Stefan said:
http://www.tiobe.com/content/paperinfo/tpci/images/tpci_trends.png

, C++ has lost half of its »market share« in relation to C
since 2003.

I've took a quick peek on how they compiled their data and I don't see how
it is possible to extract any meaningful result from that index.
According to the site[1], their test ammounts to nothing more than running
search queries on programming languages on half dozen sites picked up
almost at random from a specific site. To give an example, according to
their search criteria, they base their evaluation on what programming
language has a larger market share than some other language on the number
of search results they get from youtube and facebook. You take your own
conclusions from that.


Rui Maciel

[1] http://www.tiobe.com/content/paperinfo/tpci/tpci_definition.htm
 
R

Rui Maciel

Balog said:
Market share? The png's title says "Community index".


And from the description of their accounting method it should read "web
noise".


Rui Maciel
 
R

Rui Maciel

Krice said:
I'm the first person in the world who wrote a roguelike with zero
bugs.
A thing like that didn't even exist before I made that possible.
I'm not good, I'm the best.

And the most humble too, to boot.


Rui Maciel
 
R

Rui Maciel

Rui said:
Stefan said:
http://www.tiobe.com/content/paperinfo/tpci/images/tpci_trends.png

, C++ has lost half of its »market share« in relation to C
since 2003.

I've took a quick peek on how they compiled their data and I don't see
how it is possible to extract any meaningful result from that index.
According to the site[1], their test ammounts to nothing more than
running search queries on programming languages on half dozen sites
picked up
almost at random from a specific site. To give an example, according to
their search criteria, they base their evaluation on what programming
language has a larger market share than some other language on the
number
of search results they get from youtube and facebook. You take your own
conclusions from that.


Rui Maciel

[1] http://www.tiobe.com/content/paperinfo/tpci/tpci_definition.htm

As an attempt at an objective evaluation, we can check sourceforge's
project trove and count the number of projects associated with a given
programmng language. We have:

Java 46,457 http://sourceforge.net/softwaremap/?&fq[]=trove:198
C++ 37,078 http://sourceforge.net/softwaremap/?&fq[]=trove:165
PHP 30,193 http://sourceforge.net/softwaremap/?&fq[]=trove:183
C 28,204 http://sourceforge.net/softwaremap/?&fq[]=trove:164
C# 13,593 http://sourceforge.net/softwaremap/?&fq[]=trove:271
Python 13,460 http://sourceforge.net/softwaremap/?&fq[]=trove:178
etc etc etc...


Rui Maciel

[1] https://github.com/languages
 
S

Stefan Ram

Rui Maciel said:
And from the description of their accounting method it should
read "web noise".

The curves, however, agree with what I observe elsewhere:

The rise of Ruby in 2006, the rise of objective C in recent
years due to products of a certain manufacturer, a gradual
decline of Perl and so on. Certain, the data /is/ noisy,
but it cannot be all noise. I would apply some moving
average filter to the curves to make them more smooth.

Here is another view from another source:

http://www.google.com/trends?q=C+programming,C+++programming

. What do these curves mean? Random noise plus a systematic bias?
 
S

Stefan Ram

Rui Maciel said:
As an attempt at an objective evaluation, we can check sourceforge's

TIOBE at least does not claim that their evaluations was »objective«!
(Ok, you wrote »an attempt«.)
project trove and count the number of projects associated with a given
programmng language. We have:

Still, it is reasonable and helpful to look at the number of
Sourceforge projects as another source.
 
N

Nobody

According to

http://shootout.alioth.debian.org/...

C++ is not much faster than C

Actually, it says:
Which programming languages are fastest?

No. Which programming language implementations have the fastest
benchmark programs?

You won't notice the difference between C and C++ until you start looking
at non-trivial programs.

At the lowest level, there isn't really much difference between C and C++.
Some early C++ compilers were little more than preprocessors which
translated C++ to C in a fairly direct manner.

But the abstraction involved in writing a non-trivial program in C tends
to require performance compromises which can often be avoided in C++ by
the use of templates.
and according to

http://www.tiobe.com/content/paperinfo/tpci/images/tpci_trends.png

, C++ has lost half of its »market share« in relation to C
since 2003.

Aside from the fact that those numbers have about as much rigour as
reading tea leaves, that doesn't really surprise me.

At one time, the software development market was split mostly between C
and C++, with "all other languages combined" coming in third place. Since
then, several other languages (e.g. Java, C#) have managed to obtain
critical mass in application development, other programming models (e.g.
web applications) have taken a significant slice of the market, and
computers have gotten faster, meaning that it's more realistic to trade
some amount of efficiency for other factors (reliability, portability,
development cost).
However, C++ is much more complicated and large than C.

I don't think you'll find any disagreement there.
When the market share continues to decline, C++ will become
a legacy language of the 90s.

It won't become a "legacy" language until it stops being a sensible choice
for new code in any context, which will only happen when something else
fills its current niche. That niche will get smaller, due to increasing
hardware performance making software efficiency less critical, but it
isn't going to go away.

You can see the trade-offs at work in the enterprise arena, where Java has
made huge inroads. The increased robustness (from bounds checking, safe
pointers, checked exceptions etc) and reduced development costs (from
having all of C++'s complicated aspects eliminated) more than outweight
the efficiency penalties. When you're writing software for a single
customer, buying faster hardware is cheaper than hiring more programmers
and/or more-experienced programmers.

Conversely, the trade-offs work the other way for game development, where
you're looking to sell tens of millions of copies at tens of dollars per
copy, and want the best possible performance on whatever hardware the user
has.
 
N

Nobody

RAII helps to release resources even in the case of exceptions.
But C does not have exceptions. So RAII is not needed for this.

C does, however, have (early-) return, break/continue/goto, and longjmp().
All of which create headaches for resource management, i.e. either needing
to add many nearly-identical copies of any clean-up code or just foregoing
the use of any of the above mechanisms.

The basic OOP concepts of objects and classes (with virtual methods) can
be implemented easily enough in C (look at a C GUI toolkit such as Xt or
GTK), but RAII is the point at which you have to decide whether to go to
C++ or go without.
 
G

gwowen

  RAII helps to release resources even in the case of exceptions.
  But C does not have exceptions. So RAII is not needed for this.

  RAII helps to do one thing »alloc()« at block entry and another
  thing »release()« at block exit. This can be done in C using:

if( a = alloc() ){ rest(); release( a ); }.

True, but that idiom doesn't scale terribly elegantly. To follow the
example given in the article, if you're making a linked list of
dynamically allocated object, and the system runs out of memory on n-
th object then you need to make sure the previous n-1 objects are
correctly deallocated at the error. In C, that's definitely possible,
but its quite unpleasant - not least because your unwinding code will
likely need to be close to the creation code, which makes your code
harder to read. Also, assuming you're in a function you need some
means to communicate that error up the call-chain, which will usually
mean overloading a special value of an integer return type [which the
calling program will forget to check anyway :)] or setting a global
errno [ditto, and non-reentrant/thread-safe to boot].

RAII and exceptions lets the programmer program the common path
(resources are abundant), and gives automatic error propagation for
failure cases (using a higher level abstraction - which can be handled
at the appropriate logical level).
 

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,744
Messages
2,569,483
Members
44,901
Latest member
Noble71S45

Latest Threads

Top