Why C++ is vastly superior to C

I

Ian Collins

Ian said:
I was asking [the group] in general about "synergy". But on the C++
topic, I was suggesting that C++ exceptions (not exceptions in
general) depend on RAII. A one-way dependency rather than a mutual
one.

C++ exceptions depends on destructors.

Destructors that DO SOMETHING (RAII and other cleanup). Yes, the
mechanics are related also, but the language (semantics) was really the
point (I think!).
Without destructors, some form
of finally block is required.

RAII also depends on destructors.

So what's your take on the synergy thing? Is there any in this case? Can
there be synergy where there is dependency?

Buggered if I know, I'm an engineer, not a philosopher!
 
M

MikeP

Paavo said:
MikeP said:
Keith said:
Keith H Duggar wrote:
[...] 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?

Of the quest to make user-defined types behave like built-in types.

Built-in types don't have destructors, do they?

You're missing the point. To endow user-defined types (UDTs) with
reasonable lifetime semantics, some kind of setup/teardown construct(s)
are required. Constructors/destructors are more like a discovery than an
invention.
 
B

Balog Pal

Kai-Uwe Bux said:
In terms of likelyhood of bugs, I think it's not so much a difference in
total number of bugs per line but a difference in distribution. The error
patterns will be different. The implicit coding style can help to avoid
many
bugs. If you put clean up code in the destructor, it will be very hard to
_not_ execute it at the appropriate point.

I definitely agree with different distribution. As theat "implicit" code the
ctors and dtors are executed, with healthy guidelines you can say goodby to
"uninitialized" and "leak" classes of bugs. This IME is a huge source with
great produce. Do I get your assertion right: you claim that we get similar
amount of other problems in the exchange? My observation has big
difference, I'd guss by 2 orders of magnitude or even more.
Exceptions in templated code, on
the other hand, can lurk at places where you don't espect them diverting
control flow to a point determined by the type of the exception thrown
(and
within a template, that can be an unknown type, whence the target of the
jump is unknown, too).

I don't get this part. IME I write the big majority of C++ code as
'exception transparent'. It is a very rare case I bother to look at
exception spec of any called stuff: just expect any letter may emit an
exception. (What may be close to reality too -- if the implementation just
use a string as temporary, you immediately gain bad_alloc potentially.)
While the situation where it actually matters is rare. And in those rare
situations you pay attention anyway.

This applies to any normal function. How templates bring in anything
fundamentally new? You can't tell what T is and dependent stuff actually
does -- but should you care more? There are some special cases where you
require a nothrow guarantee, say for dtors and swap() -- but it is the same
for nontemplates.

May our observations differ due to difference in basic view of code: my
based on 'any point is an exit; where we expect otherwise needs
documentation' and you go the opposite thinking default is nothrow?
On the other hand, not seeing those jumps written
explicitly, can improve readability of the code; and having client code
determine the target of the jump even allows for greater flexibility than
goto -- whether that is good or bad, I guess, depends on the perspective.

The difference in readability is heaven and hell ;-). With the insult
added to injury that all the "alternate" paths execute only "exceptionally",
but take over 80% of the source. Just killing the possibility of
abstraction. As instead of

DoSomething(par1, par2, par3);

that was the intention, at least you must write

if (DoSomething(par1, par2, par3))
{ some handling }

At every place in client code. I rather not even start what proliferation
occours if par1 above had a conversion, especially one involving memory
allocation. Eg. in function argument was string but par1 was "Hello world".

It will create a bunch of implicit, inisible code -- constructing a
temporary, destructing it, adding a throw point. I do not deny the
*possiblility* of surprise caused by any of those.

But if the intent was as written: call that very function with that very
argument, the explicit mass of code would be there as well, as a noise
making a 5 second review into a 5 minute one for that single command. And
if intent was different, the problem is not really in the implicit code --
and I'd think with black noise stripped it is easier to discover.

Also, the correct, but "inefficient" code is normally preference to fast but
buggy one; and we have great tools that count calls and elapsed time, so in
the time you do not spend on hunting bugs it's possible to pay attention to
the 2-3 spots where you can tune away a temporary.
In terms of better/worse software, I do not see any evidence either way.

I recall Mike Howard stating in Writing Secure Code, that conversion to use
*any* kind of "string class" instead of C counterpart lead to extreme drop
of critical problems that lurked for years. i experienced a ton of evidence
how RAII based code drops bug count (not only the immediately related ones),
development time, and overall health of the project and its development.
It
seems that other factors are much more decisive. In the end, it's not the
language alone but a tupel

(group of developers, languages used, toolchain, ...)

that influences overall quality of the result.

If by that you mean that any language or language feature will not solve any
problem (aka 'No silver bullets'), of course.

I think in assuming a good process with competent and motivated people.
(meaning they know their tools whatever those are). Having that, different
tools and language features DO create a big difference. Allowing to spend
the programmers' time on writing the meat instead of hand-crafting all the
"noise".
This is not to say that
changing a single element in the tupel does not have an effect. But in one
setting going from C to C++ can boost the quality and in another setting
it
can make things worse.

Well, if you take a working C team novive in C++ and just tell them to start
writing C++ code, picking up featires along the way it is sure recipe for
disaster. ;-) You need competence. No doubt, gaining it for C++ is way
more work. But the bright side is, it can be done with just a few C++ gurus
put in charge, who mentor the others and review all the code until everyone
is familiar wit the gotchas.

Upshot:
=======
It think, for any particular project, there is a practical difference in
choosing C++ or C or (insert other language here). Making the right choice
will improve work flow and quality of the developed program. However, what
the "right choice" is depends on many factors and the "right choice" is
not
uniform.

Sure.

I am not sure whether that qualifies as a "practical difference" in the
sense of your question. But surely, choosing C++ or C is a consideration
of
practical importance. I would, however, venture the following conjecture:
whether the explicit/implicit distinction will have any seizable weight in
choosing the language probably depends more on the developers involved
than
the task at hand.

And we know all too well, that people will chose "the familiar way".
Especially in stress. Even in cases where they already learned that their
familiar way is wrong in long and short term...
 
K

Keith H Duggar

MikeP said:
Keith said:
Keith H Duggar wrote:
[...] 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?
Of the quest to make user-defined types behave like built-in types.

Built-in types don't have destructors, do they?

In C they have neither constructors nor destructors. They begin
life uninitialized (disregarding zero initialization of statics
which is a different matter) and they meet a silent trivial end.

KHD
 
K

Keith H Duggar

Paavo said:
Keith H Duggar wrote:
Keith H Duggar wrote:
[...] 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?
Of the quest to make user-defined types behave like built-in types.
Built-in types don't have destructors, do they?

You're missing the point. To endow user-defined types (UDTs) with
reasonable lifetime semantics, some kind of setup/teardown construct(s)
are required. Constructors/destructors are more like a discovery than an
invention.

Presuming that you would agree C structs have "reasonable lifetime
semantics" and that they have no destructors, it seems to me quite
a stretch to say destructors were a "discovery".

Anyhow, whether they were a "discovery" or "innovation", C does not
have user defined automatic constructors/destructors. C++ does. And
to me that was a significant advance. One that proved more powerful
and useful than I'm guessing was even realized at the time.

KHD
 
N

none

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.

"To each their own" is only valid if you write code only for
yourself. If you are a professional programmer and are paid to write
code that will become the property of someone/something else and will
most likely need to be maintained in the future by someone else than
yourself, then using your own personal hand crafted tool when a
standard tool would be perfectly suited is demonstrably a bad thing.

Yannick
 
J

jacob navia

In conclusion, the reason why a home is vastly inferior
to a skyscraper can be summarized with one single sentence:

A home has no support for supersonic elevators needed to go to floor 487.

You will never be able to rocket through 486 floors in 75.8 seconds
in a home. Never.

You may live better though.

:)
 
M

MikeP

none said:
[QUOTE="MikeP said:
Indeed, I forego many of the C++
"built-in" offerings for ones that I craft myself.

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.

"To each their own" is only valid if you write code only for
yourself. If you are a professional programmer and are paid to write
code that will become the property of someone/something else and will
most likely need to be maintained in the future by someone else than
yourself, then using your own personal hand crafted tool when a
standard tool would be perfectly suited is demonstrably a bad thing.

Yannick[/QUOTE]

Hey Yannick, I really don't have time for less than 10 points above my IQ
(and EQ) AND 10 years my senior.
 
M

MikeP

Keith said:
Paavo said:
Keith H Duggar wrote:
Keith H Duggar wrote:
[...] 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?
Of the quest to make user-defined types behave like built-in types.
Built-in types don't have destructors, do they?

You're missing the point. To endow user-defined types (UDTs) with
reasonable lifetime semantics, some kind of setup/teardown
construct(s) are required. Constructors/destructors are more like a
discovery than an invention.

Presuming

On "presumption", yeah, I'm gonna write a book about that, "soon". Maybe
I'll call it "C++ Gotchas", or something. Yeah, I'm gonna write that one.
Maybe you are one of Eric Weis's minions? (Oh yeah, he got me "fair and
square"). (For "the record": I don't hate him).
that you would agree

I would "agree" (I think you will agree to this), that you should not get
in my face and tell me what "would agree" upon. (Read: get the **** out
of my face, punk, I'm not your father).
C structs have "reasonable lifetime
semantics" and that they have no destructors, it seems to me quite
a stretch to say destructors were a "discovery".

I'm a "language designer", in the sense that the "prevailing sense" makes
no sense at all and I do it better. So I can't banter here with y'all
language-lawyer-wannabes. You will live, you will die. You will have some
span in between those 2 things. Those who want to establish a SUCK 3rd
position, suck.
Anyhow, whether they were a "discovery" or "innovation", C does not
have user defined automatic constructors/destructors.

C does not have class objects.
C++ does. And
to me that was a significant advance.

You don't know "advance". "Youth is wasted on the young". Why don't you
go vote. I mean, fine. Vote. And while you are their, raise their flag
(high). OOPs, the "FLAG", surely you know it. "Pledge of Allegience",
recite now, so your computer file can be updated.

Test (note that willing participant who "answers", will be held liable
for his "freedom of speech"):

What is a flag?

Is a flag rape?

Should flags be burned?

Do you feel raped by a flag?

Do you feel you will be draped by a flag?

Do flags rape?
 
M

MikeP

jacob said:
In conclusion, the reason why a home is vastly inferior
to a skyscraper can be summarized with one single sentence:

A home has no support for supersonic elevators needed to go to floor
487.
You will never be able to rocket through 486 floors in 75.8 seconds
in a home. Never.

You may live better though.

:)

I owe you what?
 
M

MikeP

jacob said:
In conclusion, the reason why a home is vastly inferior
to a skyscraper can be summarized with one single sentence:

A home has no support for supersonic elevators needed to go to floor
487.
You will never be able to rocket through 486 floors in 75.8 seconds
in a home. Never.

You may live better though.

:)

Lament not your old age, lament those that politics will kill, if you
observe the abhorance of killing people for someone else's cause. I am a
person. And I hold all that came before me in contempt.

No I won't celebrate your killing. I will celebrate the death of your
flag. Send someone to war? You got it comin. :p You do suck, anyone who
imposes their will upon another. Time is not your friend if your "heart"
is not true. Cry for those dead under your regime. Pfft. I cry that you
continue that.
 
G

gwowen

In conclusion, the reason why a home is vastly inferior
to a skyscraper can be summarized with one single sentence:

A home has no support for supersonic elevators needed to go to floor 487.

Now, excuse me, I've got to go and work on getting the house standards
committee to give planning permission for this rickety, unsafe, steam-
powered 19th century escalator that I'm bolting to the outsides of my
house (I've put an emergency exit half way up - in case the whole
thing starts to collapse - but its the tenants job to provide enough
mattresses for a soft landing). Because that's all the help anyone
will ever need to get upstairs.

/ Hey! That's not a car analogy. Minus 5 points.
 
N

none

Hey Yannick, I really don't have time for less than 10 points above my IQ
(and EQ) AND 10 years my senior.

Sorry Mike but you started here having a discussion. Some of the
points you raised are let's say controversial or at least not everyone
are in agreement with. However, until your last few posts, you were
acting as a positive contributor attempting to have a worthwhile
technical discussion. Your alternate point of view was actually
interesting and worthwhile to consider.

Have you decided that you were not interested in having a valid and
constructive technical discussion but would rather become a negative
contributor to this newsgroup?

Regards
Yannick
 
J

Juha Nieminen

Joshua Maurice said:
Imagine you have a container, such as std::vector. There are two basic
ways to implement it, as C++ std::vector, or as you have to in C with
void pointers, or as you would in Java with their equivalent of
pointers eg: ArrayList.

It's a tradeoff. With the C approach (equivalently
java.util.ArrayList), there is one piece of assembly corresponding to
that function for all possible instantiations of the container class
and for all possible contained types. With the std::vector approach,
you can have a different piece of assembly in the object file for each
different type used to instantiate the template. That is,
std::vector<int> and std::vector<char> can (and usually will) be
compiled down to different functions in the object file, distinguished
by name mangling. Thus, the template way results in less instructions
executed compared to the void pointer approach, but it results in
larger executables.

You chose a pretty poor example because it's so easy to refute.

Firstly, consider the std::vector versus the C array containing void
pointers to the elements (which I suppose are each dynamically allocated
individually). The elements in the std::vector will be tightly packed
in memory into one single array. The C array will have a memory overhead
for each array element of one pointer plus whatever ancillary space the
memory allocator needs for each allocated block (which varies from 4 to 8
and even more bytes depending on the situation and architecture).

Thus, any possible saving that there could be from having single
functions handling all arrays of the same type will be lost because of
the additional memory consumption of the data itself. The more elements
in the array, the more the memory consumption overhead will tilt to the
C side.

This is especially so because the functions in std::vector tend to be
really small and inline very well. So well that many of the functions will
basically disappear completely because they will be fully merged into the
calling code. (For example, std::vector indexing will end up being completely
equivalent to indexing a raw array. Also std::vector iterators are usually
plain pointers. Hence there's no space difference depending on which type
is being used and how many there are. In other words, there will be no
space difference compared to a "generic" C implementation using void
pointers.)

In fact, it might even happen that the std::vector version will, quite
ironically, produce a *smaller* executable than the "generic" C version
(because the compiler can inline better), even if more than one type is
being used. (No, I haven't tried this, but I wouldn't be surprised if that
was the case.)

Add to this that there will also be speed overhead with the C version
that is not there in the std::vector version. Not only do accesses have
extra indirection steps, but allocating individual elements separately
will decrease data locality and increase memory fragmentation (not to
talk about the fact that allocation and deallocation is a quite slow
operation). Even if the executable binary was smaller, any cache benefits
resulting from this could well be nullified by the cache unfriendliness of
the data being handled.

Even if the templated version produced larger binaries, how much larger,
compared to an equivalent implementation without templated code? Can we
honestly talk about "bloat"?
 
J

Juha Nieminen

Stefan Ram said:
When code is smaller, the chance is greater that it might fit in some
cache, which will make it execute much faster.

Just because the executable is larger overall doesn't mean that the
functions are larger.
 
S

Stefan Ram

Juha Nieminen said:
Just because the executable is larger overall doesn't mean that the
functions are larger.

In this case, there must be many small functions. Since
functions usually call each other, they might have to be
swapped in and swapped out of the limited cache.

Would there only be few small functions, all of them would
fit into the limited cache.
 
R

Rui Maciel

hanukas said:
That's not very relevant as I don't think a FIFO is very popular
replacement strategy for cache.

I believe you didn't quite understood it. The main point, which Belady's
anomaly demonstrates, is that there isn't necessarily a direct correlation
between how much cache a program takes up and the number of cache misses.
If it isn't possible to assume a direct correlation between how much cache
a program takes up and the number of cache misses then it isn't possible
to claim that a specific variation in a program's size has a specific
impact on how fast a program is ran. If the subject being discussed is
the relation between a program's size and the influence that size may have
on how fast that program runs, particularly due to the number of cache
misses it generates, then it is obviously relevant.


Rui Maciel
 
J

jacob navia

Le 25/05/11 12:15, Rui Maciel a écrit :
I believe you didn't quite understood it. The main point, which Belady's
anomaly demonstrates, is that there isn't necessarily a direct correlation
between how much cache a program takes up and the number of cache misses.
If it isn't possible to assume a direct correlation between how much cache
a program takes up and the number of cache misses then it isn't possible
to claim that a specific variation in a program's size has a specific
impact on how fast a program is ran. If the subject being discussed is
the relation between a program's size and the influence that size may have
on how fast that program runs, particularly due to the number of cache
misses it generates, then it is obviously relevant.


Rui Maciel

Yes, you are right in principle. It is conceivable that a huge
program uses only a small fraction of its executable foot print
and all of it fits in the cache.

It is also conceivable that a program has a huge footprint but
it has almost no jumps so that its cache misses are exceptionally
low because when code is loaded all of it is used in highly
efficient loops.

And there could be more of those situations.

ALl I can tell you is that in my experience both the above
cases aren't found "in nature"...

What I did find of course, is that huge programs tend to
trash around a lot jumping from one small method to the
next one...

THAT is surely a common observation.

jacob
 

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,774
Messages
2,569,598
Members
45,157
Latest member
MercedesE4
Top