Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Oozing poison

109 views
Skip to first unread message

AD

unread,
Jan 10, 2012, 7:35:31 AM1/10/12
to
I kid you not, I found this trash in a real project:

//Remove texture from the the stack and try to unload from memory
void resourceManager::popTexture(const char* nickName)
{
BOOL removed = false;
for (std::vector<texture*>::iterator itr = textures.begin(); itr !=
textures.end();)
{
if ( (*itr)->nickName == nickName )
{

Leigh Johnston

unread,
Jan 10, 2012, 10:19:19 AM1/10/12
to
If texture::nickName is a std::string I can see nothing wrong with this
code snippet.

Posting such partial code snippets which lack sufficient context are
time wasting at best.

/Leigh

Jorgen Grahn

unread,
Jan 10, 2012, 4:42:27 PM1/10/12
to
I don't see anything unusually bad about it. I assume there's a itr++
elsewhere, and that texture::nickName is a std::string.

/Jorgen

--
// Jorgen Grahn <grahn@ Oo o. . .
\X/ snipabacken.se> O o .

AD

unread,
Jan 11, 2012, 3:43:32 AM1/11/12
to
that's exactly what the person who wrote that piece of code did.
made assumptions without verifying it wasting my time in the process.
now for the actual texture class definition:

typedef struct texture
{
texture(TextureInfo *glTexture_, const char *nick) :
glTexture(glTexture_), nickName(nick)
{

}
const char *nickName;
TextureInfo *glTexture;
}texture;

c++ is trash not only because of the gawd ugly syntax but because of
the coding style in results in
the resulting black hole of ungawdly maintenance inflicted on
unsuspected continued engineers

Alf P. Steinbach

unread,
Jan 11, 2012, 4:01:25 AM1/11/12
to
On 11.01.2012 09:43, AD wrote:
> On Jan 10, 5:19 pm, Leigh Johnston<le...@i42.co.uk> wrote:
>> On 10/01/2012 12:35, AD wrote:
>>
>>> I kid you not, I found this trash in a real project:
>>
>>> //Remove texture from the the stack and try to unload from memory
>>> void resourceManager::popTexture(const char* nickName)
>>> {
>>> BOOL removed = false;
>>> for (std::vector<texture*>::iterator itr = textures.begin(); itr !=
>>> textures.end();)
>>> {
>>> if ( (*itr)->nickName == nickName )
>>> {
>>
>> If texture::nickName is a std::string I can see nothing wrong with this
>> code snippet.
>>
>> Posting such partial code snippets which lack sufficient context are
>> time wasting at best.
>>
>
> that's exactly what the person who wrote that piece of code did.
> made assumptions without verifying it wasting my time in the process.
> now for the actual texture class definition:
>
> typedef struct texture
> {
> texture(TextureInfo *glTexture_, const char *nick) :
> glTexture(glTexture_), nickName(nick)
> {
>
> }
> const char *nickName;
> TextureInfo *glTexture;
> }texture;

The author of that code mixed up C and C++. The typedef only makes sense
in C (but the code will not compile as C). The constructor only makes
sense in C++ (but the typedef is meaningless in C++).



> c++ is trash not only because of the gawd ugly syntax but because of
> the coding style in results in
> the resulting black hole of ungawdly maintenance inflicted on
> unsuspected continued engineers

Let's not condemn a language just because it's used by at least one
incompetent person.

And let's not condemn that person for wasting others' time, when we're
doing the same right here. :-)


Cheers & hth.,

- Alf

Ian Collins

unread,
Jan 11, 2012, 4:09:48 AM1/11/12
to
Using a type "BOOL" also hints at a confused author.

--
Ian Collins

AD

unread,
Jan 11, 2012, 4:42:46 AM1/11/12
to
the only difference is that structs are by default public and clas is
by default private.
but i guess this garbage initially started its life as code to be
"improved" later with c__

> > in C (but the code will not compile as C). The constructor only makes
> > sense in C++ (but the typedef is meaningless in C++).
>
> Using a type "BOOL" also hints at a confused author.
>

yeah, somehow vanilla objective c was not enough for them.
they just HAD to use objective c++

with predictable results


4. Alf P. Steinbach
View profile
More options Jan 11, 11:01 am
On 11.01.2012 09:43, AD wrote:

- Show quoted text -

The author of that code mixed up C and C++. The typedef only makes
sense
in C (but the code will not compile as C). The constructor only makes
sense in C++ (but the typedef is meaningless in C++).

> c++ is trash not only because of the gawd ugly syntax but because of
> the coding style in results in
> the resulting black hole of ungawdly maintenance inflicted on
> unsuspected continued engineers

Let's not condemn a language just because it's used by at least one
incompetent person.

> And let's not condemn that person for wasting others' time,

yeah, except I see the same pattern over and over and over
in all c++ garbage that comes my way: the left hand did not know what
the right one
was doing with disastrous results (the cretin who wrote this
had seen fit to use handmade refcounting
instead of relying on the built in mechanism in NSObject)

Predictably now another person (me) is faced with underrefs & co
in that fragile inconsistent p.o.s.

I'll illustrate the problems with this hack of a language further once
I get another
suitable snippet

Leigh Johnston

unread,
Jan 11, 2012, 8:36:55 AM1/11/12
to
> Predictably now another person (me) is faced with underrefs& co
> in that fragile inconsistent p.o.s.
>
> I'll illustrate the problems with this hack of a language further once
> I get another
> suitable snippet

Posting code snippets of colleague's code and then calling said
colleague a "cretin" in a public forum such as this is not very
professional.

/Leigh

John Bokma

unread,
Jan 11, 2012, 11:08:07 AM1/11/12
to
Leigh Johnston <le...@i42.co.uk> writes:

[..]
That, and the quoting disaster via Google Groups...

--
John Bokma j3b

Blog: http://johnbokma.com/ Perl Consultancy: http://castleamber.com/
Perl for books: http://johnbokma.com/perl/help-in-exchange-for-books.html

Jorgen Grahn

unread,
Jan 11, 2012, 11:50:08 AM1/11/12
to
On Wed, 2012-01-11, AD wrote:
> On Jan 10, 5:19 pm, Leigh Johnston <le...@i42.co.uk> wrote:
>> On 10/01/2012 12:35, AD wrote:
>>
>> > I kid you not, I found this trash in a real project:
...
> c++ is trash not only because of the gawd ugly syntax but because of
> the coding style in results in
> the resulting black hole of ungawdly maintenance inflicted on
> unsuspected continued engineers

If /that/ example is enough to make you rant & rave on Usenet, you
probably haven't been doing maintenance programming for very long!

I've been doing lots of it. Some points:

- You will see much scarier things than that.

- Maintenance programming can be both fun and a quick way to
become a better programmer. I pity the people who write code
from scratch, test it some, and then hand it over to some
maintenance organization. They miss out one some very important
lessons.

- I seriously doubt that C++ maintenance nightmares are worse
than Perl, Python or whatever maintenance nightmares.

My experience is only with C and C++. Of those two, C++ code is
easier to debug and clean up, because you can lock things up, in
steps, turning bugs from run-time errors to compile-time ones.

AD

unread,
Jan 12, 2012, 9:04:34 AM1/12/12
to
On Jan 11, 6:50 pm, Jorgen Grahn <grahn+n...@snipabacken.se> wrote:
> On Wed, 2012-01-11, AD wrote:
> > On Jan 10, 5:19 pm, Leigh Johnston <le...@i42.co.uk> wrote:
> >> On 10/01/2012 12:35, AD wrote:
>
> >> > I kid you not, I found this trash in a real project:
> ...
> > c++ is trash not only because of the gawd ugly syntax but because of
> > the coding style in results in
> > the resulting black hole of ungawdly maintenance inflicted on
> > unsuspected continued engineers
>
> If /that/ example is enough to make you rant & rave on Usenet, you
> probably haven't been doing maintenance programming for very long!
>
> I've been doing lots of it. Some points:
>
> - You will see much scarier things than that.
>
> - Maintenance programming can be both fun and a quick way to
>   become a better programmer. I pity the people who write code
>   from scratch, test it some, and then hand it over to some
>   maintenance organization.  They miss out one some very important
>   lessons.
>
> - I seriously doubt that C++ maintenance nightmares are worse
>   than Perl, Python or whatever maintenance nightmares.
>
with c like languages you don't have code rot,
with python my experience is of a write-and-forget variety

Just Works (tm)

>   My experience is only with C and C++.  Of those two, C++ code is
>   easier to debug and clean up, because you can lock things up, in
>   steps, turning bugs from run-time errors to compile-time ones.
>

I'm much happier after stopping c++ coding in favor of c++less
objective c.
have to use mm extension only when using c++ frameworks such as
cocos2d
but that's pretty much it

AD

unread,
Jan 12, 2012, 9:08:53 AM1/12/12
to
probably, though as i get older i care much less about being
"professional"
and much more about being true. though the evidence of problems swept
under
the carpet in the original code does not leave a whole lot of basis to
reciprocate
on top of

integrity is a great trait: try to cultivate that for a while to see
what I mean

honesty is another good one. try telling the customer "this feature is
more
than you've paid for, moroever it's likely to turn the codebase
into an unmaintainable piece of shit" next time you are contracted.
a whole lot of goodwill towards you might be expected on their part.
if not they are unreasonable iDiots. Next!

Leigh Johnston

unread,
Jan 12, 2012, 9:13:39 AM1/12/12
to
Still no reason to wash the dirty linen in public; you have to consider
your company's reputation as well as the customer's. Be professional
and solve such problems in private.

/Leigh

Victor Bazarov

unread,
Jan 12, 2012, 10:13:39 AM1/12/12
to
On 1/12/2012 9:04 AM, AD wrote:
>[..]
> I'm much happier after stopping c++ coding in favor of c++less
> objective c.
> have to use mm extension only when using c++ frameworks such as
> cocos2d
> but that's pretty much it

So, you're not coding in C++, and you come to a C++ community hangout to
complain about C++ being difficult to comprehend, and you expect what,
sympathy? <shrug>

V
--
I do not respond to top-posted replies, please don't ask

Nick Keighley

unread,
Jan 13, 2012, 5:18:00 AM1/13/12
to
On Jan 12, 2:08 pm, AD <isq...@gmail.com> wrote:
> On Jan 11, 3:36 pm, Leigh Johnston <le...@i42.co.uk> wrote:

<snip>

> > Posting code snippets of colleague's code and then calling said
> > colleague a "cretin" in a public forum such as this is not very
> > professional.

it's also somewhat subjective

> probably, though as i get older i care much less about being
> "professional" and much more about being true.

predicates are true, people are correct or honest or tactless. Odd
most people grow out of atitudes like yours at about 14.

<snip>

> integrity is a great trait: try to cultivate that for a while to see
> what I mean
>
> honesty is another good one. try telling the customer "this feature is
> more
> than you've paid for, moroever it's likely to turn the codebase
> into an unmaintainable piece of shit" next time you are contracted.

...and you'll never work again

> a while lot of goodwill towards you might be expected on their part.

LOL

> if not they are unreasonable iDiots. Next!

its possible to critique code without being gratuitously rude. It
might be more effective as well

AD

unread,
Jan 17, 2012, 5:08:31 AM1/17/12
to
honesty is far more beneficial for the company reputation than
"professionalism"

> and solve such problems in private.
>
You still don;t understand, don't you?
I would not have had this kind of problems in the first place if there
was no c++ code in that project.
The whole point of my post is to illustrate how shitty of a language c+
+ is.
You can not fix that by subtracting from it (though revving it back to
1.2 or at least 2.0 might
make it marginally usable again. good luck squeezing toothpaste back
into the tube)
and you most certainly can't fixing it by adding more shit into c+
+--11

just jettison this hack of the language and move on to an incompatible
lean and mean offspring.
the industry will be in a much better shape with that load off the
chest

AD

unread,
Jan 17, 2012, 5:19:58 AM1/17/12
to
On Jan 12, 5:13 pm, Victor Bazarov <v.baza...@comcast.invalid> wrote:
> On 1/12/2012 9:04 AM, AD wrote:
>
> >[..]
> > I'm much happier after stopping c++ coding in favor of c++less
> > objective c.
> > have to use mm extension only when using c++ frameworks such as
> > cocos2d
> > but that's pretty much it
>
> So, you're not coding in C++, and you come to a C++ community hangout to
> complain about C++ being difficult to comprehend, and you expect what,
> sympathy?  <shrug>
>
I'm not coding in C++ ANYMORE
I could not possibly see how it can be used to write robust code

linux kernel developers at one point tried (and failed),
primirily because of the buggy g++ frontend to gcc
and you can really count on your palm c++ compilers that work okay.
(none on *nix systems)
most are full of bugs. when you can't predict how many passes you need
to
parse code you could just as well scram at that point because
it's an indication of something horrendouzly wrong with the language

but more and more leammings nevertheless insist on their journey to
nowhere

AD

unread,
Jan 17, 2012, 5:24:31 AM1/17/12
to
On Jan 13, 12:18 pm, Nick Keighley <nick_keighley_nos...@hotmail.com>
wrote:
You are right. Efficiency (as well as my well being) being the primary
concern
I should remember to multiply my estimates by a coefficient that is
tied to the amount of
c++ in the codebase I'm about to inherit

Thank you!
bye bye!

AD

unread,
Jan 17, 2012, 5:31:50 AM1/17/12
to
On Jan 10, 11:42 pm, Jorgen Grahn <grahn+n...@snipabacken.se> wrote:
> On Tue, 2012-01-10, AD wrote:
> > I kid you not, I found this trash in a real project:
>
> > //Remove texture from the the stack and try to unload from memory
> > void resourceManager::popTexture(const char* nickName)
> > {
> >    BOOL removed = false;
> >    for  (std::vector<texture*>::iterator itr = textures.begin(); itr !=
> > textures.end();)
> >    {
> >            if ( (*itr)->nickName == nickName )
> >            {
>
> I don't see anything unusually bad about it. I assume there's a itr++
> elsewhere, and that texture::nickName is a std::string.
>
yes, the person who wrote this code had (erroneously) assumed the same
thing

Henrik Faber

unread,
Jan 17, 2012, 6:50:34 AM1/17/12
to
On 17.01.2012 11:08, AD wrote:

> You still don;t understand, don't you?
> I would not have had this kind of problems in the first place if there
> was no c++ code in that project.

Right: Because in C, one could not use "==" to compare two char*. Or in
Python one could not use "is" to compare two strings.

You, Sir, are an enourmous moron.

Best regards,
Henrik

Victor Bazarov

unread,
Jan 17, 2012, 8:04:50 AM1/17/12
to
...and you're standing nearby shouting at them and hoping they're going
to listen? What are you trying to accomplish? Save the world? Get a
life. Sounds like you really would like to come back to C++ but since
you spent too much time already away from it, your grip on it (however
weak it was before) is slipping even further, and it makes you very
annoyed, irritated and angry. If it's not for you, give it up, don't
waste your time. And ours.

Miles Bader

unread,
Jan 17, 2012, 11:51:42 PM1/17/12
to
AD <isq...@gmail.com> writes:
>> So, you're not coding in C++, and you come to a C++ community hangout to
>> complain about C++ being difficult to comprehend, and you expect what,
>> sympathy?  <shrug>
>>
> I'm not coding in C++ ANYMORE
> I could not possibly see how it can be used to write robust code

You expect us to trust your judgement?

[I've found C++ _much_ easier to write robust code in compared to C.
It is clearly no proof against incompetent coders (nothing is), but it
does offer some really good tools to help competent ones...]

-miles

--
Bacchus, n. A convenient deity invented by the ancients as an excuse for
getting drunk.

AD

unread,
Jan 21, 2012, 7:40:24 AM1/21/12
to
On Jan 18, 6:51 am, Miles Bader <mi...@gnu.org> wrote:
> AD <isq...@gmail.com> writes:
> >> So, you're not coding in C++, and you come to a C++ community hangout to
> >> complain about C++ being difficult to comprehend, and you expect what,
> >> sympathy?  <shrug>
>
> > I'm not coding in C++ ANYMORE
> > I could not possibly see how it can be used to write robust code
>
> You expect us to trust your judgement?
>
> [I've found C++ _much_ easier to write robust code in compared to C.
> It is clearly no proof against incompetent coders (nothing is), but it
> does offer some really good tools to help competent ones...]
>
Well, objective-c (and it's inherent to all c based languages, unless
you start ripping out pointers, etc) is prone to allowing a single fly-
idiot
poisoning the whole barrel, and java like languages
were designed precisely to keep idiots at bay, but c++ seems to be
especially
susceptible to providing morons with tools to automate
writing some crap code.

Quint Rankid

unread,
Jan 21, 2012, 12:05:48 PM1/21/12
to
I think it would be helpful to know why you are posting to this
group. Can you please tell me what you hope to accomplish? I think
this would help those who would like to respond to whatever points
you're trying to make.

If you are simply trying to tell us that you don't like C++, then I
think it is clear that you have done that. So I tentatively conclude
that you must have some other purpose in mind. Please share it with
us.

TIA



Wil Evers

unread,
Jan 21, 2012, 1:52:00 PM1/21/12
to
Quint Rankid wrote:

> On Jan 21, 7:40 am, AD <isq...@gmail.com> wrote:
>> On Jan 18, 6:51 am, Miles Bader <mi...@gnu.org> wrote:> AD <isq...@gmail.com> writes:

>>> [I've found C++ _much_ easier to write robust code in compared to C.
>>> It is clearly no proof against incompetent coders (nothing is), but it
>>> does offer some really good tools to help competent ones...]
>>
>> Well, objective-c (and it's inherent to all c based languages, unless
>> you start ripping out pointers, etc) is prone to allowing a single fly-
>> idiot poisoning the whole barrel, and java like languages were designed
>> precisely to keep idiots at bay, but c++ seems to be especially
>> susceptible to providing morons with tools to automate writing some crap
>> code.
>
> I think it would be helpful to know why you are posting to this
> group. Can you please tell me what you hope to accomplish? I think
> this would help those who would like to respond to whatever points
> you're trying to make.

Well, AD, whoever he is, is not alone. Wasn't it Bjarne himself who
said something like "C makes it easy to shoot yourself in the foot;
C++ makes it harder, but when you do, you blow away your whole leg"?

Personally, I believe that the built-in idiot filter in C++ is a
feature: I've seen it expose quite a few problems before they could
cause any real harm. The philosophy C++ inherited from C is to
trust the programmer, who is supposed to make an informed, intelligent
choice when it comes to selecting the right tool for the right job.

Of course, that doesn't mix well with a poor management style that is
only capable of focussing on short-term labor costs.

There. Now that felt good!

- Wil

Quint Rankid

unread,
Jan 21, 2012, 2:33:35 PM1/21/12
to
On Jan 21, 1:52 pm, Wil Evers <boun...@dev.null> wrote:
> Quint Rankid wrote:

> Wasn't it Bjarne himself who
> said something like "C makes it easy to shoot yourself in the foot;
> C++ makes it harder, but when you do, you blow away your whole leg"?

http://www2.research.att.com/~bs/bs_faq.html#really-say-that
"What people tend to miss, is that what I said there about C++ is to a
varying extent true for all powerful languages. As you protect people
from simple dangers, they get themselves into new and less obvious
problems. Someone who avoids the simple problems may simply be heading
for a not-so-simple one. One problem with very supporting and
protective environments is that the hard problems may be discovered
too late or be too hard to remedy once discovered. Also, a rare
problem is harder to find than a frequent one because you don't
suspect it."

Pavel

unread,
Jan 21, 2012, 10:43:00 PM1/21/12
to
I guess, everyone's mileage varies. For a change, I am on AD side in this
C-vs-C++ maintenance/reviewing issue although for different reasons. Reading C++
code takes, in my experience, much longer time than C code of equivalent
complexity because there are on average more (commonly used) meanings for
identically-looking C++ code than C code. I have already given on this group an
example that, in C, you pretty much know that f(a) does not change a -- but not
in C++. Also, something like a+b can mean anything but addition (forget about a
<< b being always a shift) and getting certainty is prohibitively time-expensive
(last time I counted, operator<< had some 3 to 4 thousands overloads in my
organization; add to this potential automatic conversions and you get the picture).

To be on schedule, a reviewer/maintainer needs to assume; but because there are
always more than one way to skin a cat in C++, any (and I mean *any*) assumption
one developer will find reasonable will be broken not too often in another
person's code that the unfortunate first developer has to review.

Writing C++ code is a different story.. I often call C++ code I am getting for
reviews or maintenance "write-only" because it takes longer to understand what
some code does (forget about "supposed to do") than to write the equivalent
code. (yeah, I know there shall be specs that say what code shall do; the only
thing is, often there are none).

I think that's why I noticed trend about C++ developers (and related managers)
to switch roles: you code if you can, no matter how high is your level in an
organization, and leave reviewing to underlings. I think this trend is
C++-specific, because the situation with Java is opposite, in my experience:
more senior people commonly review the code. I was too late to catch this trend
timely; now trying to reposition myself back to writing.. hopefully not
write-only code.


-Pavel

Ian Collins

unread,
Jan 22, 2012, 3:05:29 AM1/22/12
to
On 01/22/12 04:43 PM, Pavel wrote:
>
> Writing C++ code is a different story.. I often call C++ code I am getting for
> reviews or maintenance "write-only" because it takes longer to understand what
> some code does (forget about "supposed to do") than to write the equivalent
> code. (yeah, I know there shall be specs that say what code shall do; the only
> thing is, often there are none).

That should be "there shall be tests that so exactly what the code
does". I certainly rely on mine when modifying my own code that's more
than a couple of projects old.

--
Ian Collins

Pavel

unread,
Jan 22, 2012, 6:21:55 PM1/22/12
to
Test results can be helpful in understanding some aspects of the code but,
paroding Murphy laws: "A reliable test of a feature of your current interest is
always missing". Also, the OP's (and oftentimes mine) issue is that we did not
write the code (or tests) we need to understand.

-Pavel

Jorgen Grahn

unread,
Jan 23, 2012, 10:55:38 AM1/23/12
to
On Sun, 2012-01-22, Pavel wrote:
...
> I guess, everyone's mileage varies. For a change, I am on AD side in this
> C-vs-C++ maintenance/reviewing issue although for different reasons. Reading C++
> code takes, in my experience, much longer time than C code of equivalent
> complexity because there are on average more (commonly used) meanings for
> identically-looking C++ code than C code. I have already given on this group an
> example that, in C, you pretty much know that f(a) does not change a -- but not
> in C++.

I don't see the problem. You review f(A&), and immediately see that it
can modify its apparent argument. So you ask yourself "will this be
obvious in the calling code, based on the name of f and so on?" If the
answer is "no", you fail the code.

> Also, something like a+b can mean anything but addition (forget about a
> << b being always a shift) and getting certainty is prohibitively time-expensive

I don't get this part of your complaint. You must review the code with
the types of objects in mind. In the expression 'a+b' a and b have
certain types, and if you know these and still cannot think of one
reasonable meaning for the expression ... well, that's a reason to
fail the code right there!

(I assume there is no deep interitance hierarchy with run-time
polymorphism involved. I can't read such code, either.)

> (last time I counted, operator<< had some 3 to 4 thousands overloads in my
> organization; add to this potential automatic conversions and you get the picture).

And how many of these were not on the form ostream << const T& ?
I find it hard to believe that standard stream output can be a problem
in this context.

gwowen

unread,
Jan 23, 2012, 11:37:51 AM1/23/12
to
On Jan 23, 3:55 pm, Jorgen Grahn <grahn+n...@snipabacken.se> wrote:
> On Sun, 2012-01-22, Pavel wrote:
>
> ...
>
> > I guess, everyone's mileage varies. For a change, I am on AD side in this
> > C-vs-C++ maintenance/reviewing issue although for different reasons. Reading C++
> > code takes, in my experience, much longer time than C code of equivalent
> > complexity because there are on average more (commonly used) meanings for
> > identically-looking C++ code than C code. I have already given on this group an
> > example that, in C, you pretty much know that f(a) does not change a -- but not
> > in C++.
>
> I don't see the problem. You review f(A&), and immediately see that it
> can modify its apparent argument. So you ask yourself "will this be
> obvious in the calling code, based on the name of f and so on?" If the
> answer is "no", you fail the code.

quite.


#define f(x) modify_x(&x)

// You can write terrible code in any except Haskell ;)
f(a);

Gernot Frisch

unread,
Jan 24, 2012, 12:21:45 PM1/24/12
to

> I could not possibly see how it can be used to write robust code

Am I feeding a troll now? :S

You can write perfectly robust code in C++ if you don't use pointers at all.
There's usually no need to do this, as other languages don't even have them.
Use references if you pass byref, and use containers if you want to allocate
to be safe.

Victor Bazarov

unread,
Jan 24, 2012, 12:41:38 PM1/24/12
to
On 1/24/2012 12:21 PM, Gernot Frisch wrote:
>
>> I could not possibly see how it can be used to write robust code
>
> Am I feeding a troll now? :S
> [..]

You are. Please don't. Thanks.

Pavel

unread,
Jan 24, 2012, 10:48:06 PM1/24/12
to
Jorgen Grahn wrote:
> On Sun, 2012-01-22, Pavel wrote:
> ...
>> I guess, everyone's mileage varies. For a change, I am on AD side in this
>> C-vs-C++ maintenance/reviewing issue although for different reasons. Reading C++
>> code takes, in my experience, much longer time than C code of equivalent
>> complexity because there are on average more (commonly used) meanings for
>> identically-looking C++ code than C code. I have already given on this group an
>> example that, in C, you pretty much know that f(a) does not change a -- but not
>> in C++.
>
> I don't see the problem. You review f(A&), and immediately see that it
> can modify its apparent argument. So you ask yourself "will this be
> obvious in the calling code, based on the name of f and so on?" If the
> answer is "no", you fail the code.
Even letting alone that failing all such code you encounter prevents you from
staying on schedule:

If you do not review but maintain it as in OP case -- what do you do then?

>
>> Also, something like a+b can mean anything but addition (forget about a
>> << b being always a shift) and getting certainty is prohibitively time-expensive
>
> I don't get this part of your complaint. You must review the code with
> the types of objects in mind. In the expression 'a+b' a and b have
> certain types, and if you know these and still cannot think of one
> reasonable meaning for the expression ... well, that's a reason to
> fail the code right there!
Same question as above.

>
> (I assume there is no deep interitance hierarchy with run-time
> polymorphism involved. I can't read such code, either.)
>
>> (last time I counted, operator<< had some 3 to 4 thousands overloads in my
>> organization; add to this potential automatic conversions and you get the picture).
>
> And how many of these were not on the form ostream<< const T& ?
More than a half. People create other classes than standard streams, most of
them having stream-like (but not quite) semantics, for example for IPC purpose,
some with different semantics. An example of the issue is that something like
somestream << "abc" can lead to very different serializations for different
types of the stream depending on whether there is an operator<< with const char
* or some conversion is to be called. And of course it is not clear from the
call site whether such operator is defined (sometimes it matters, too, whether
it is defined as a member of the stream-like class or free-standing function).

> I find it hard to believe that standard stream output can be a problem
> in this context.
Well, believe it or not, it takes more time, sometimes many times so, to read
this code with complete understanding of whether there is bug there (let alone
what exactly will be in the output) even for ostream-like first arguments (which
is, as I mentioned earlier, is not always the case) than something printf-like
and this is a problem.

>
> /Jorgen
>

-Pavel

AD

unread,
Jan 25, 2012, 5:07:02 AM1/25/12
to
I don't see how you could maintain any reasonable quality of c++
project
even if you keep the team in the git jail and have the subproject
stakeholders
responsible for their parts.
As I said linux kernel dev tried and failed miserably: c++(compilers)
were not as bloated
with features back then.

But I guess I'm preaching here in vain.

---
Some blame the management, some the employees
Everybody knows it's the industrial disease (TM)

AD

unread,
Jan 25, 2012, 5:23:39 AM1/25/12
to
that's a very blanket and vague statement

he should try to get into senate -> being there is all about
saving face and never utter anything remotely resembling
"yes, i fucked up big time: but look at all the suckers
who followed me in my footsteps!"

Victor Bazarov

unread,
Jan 25, 2012, 7:59:06 AM1/25/12
to
On 1/25/2012 5:07 AM, AD wrote:
> [..]
> But I guess I'm preaching here in vain.

Stop preaching then and start doing something useful. It's *you* who's
"oozing poison"; the sooner you realize that, the better.

Ian Collins

unread,
Jan 25, 2012, 1:54:05 PM1/25/12
to
On 01/25/12 11:07 PM, AD wrote:
>
> I don't see how you could maintain any reasonable quality of c++
> project

Just because you lack the skills to manage a quality C++ project,
doesn't assume others can't.

> But I guess I'm preaching here in vain.

Preaching in ignorance more like.

--
Ian Collins

Rui Maciel

unread,
Jan 25, 2012, 2:44:40 PM1/25/12
to
AD wrote:

> I'm not coding in C++ ANYMORE
> I could not possibly see how it can be used to write robust code

I could not possibly see how matter can consist of arrangements of a dozen
types of sub-atomic particles.

Then again, I'm no particle physicist. So that explains it.


> linux kernel developers at one point tried (and failed),
> primirily because of the buggy g++ frontend to gcc
> and you can really count on your palm c++ compilers that work okay.

Taken from the linux kernel mailing list FAQ:

Why don't we rewrite the Linux kernel in C++?
http://www.tux.org/lkml/#s15-3

They didn't actually failed to write the linux kernel with C++. They only
opted to discontinue to write code that compiled under g++ due to
performance issues.

If you take the time to discover the reasons behind the decision by the
linux kernel team not to use C++ to write kernel code, you will notice that
every single reason they point out is related to the use of C++ to write
kernel code. The keyword here is "kernel code".

Having said that, I'll point out what they state regarding the C++
programming language:

<quote>
My personal view is that C++ has its merits, and makes object-oriented
programming easier. However, it is a more complex language and is less
mature than C. The greatest danger with C++ is in fact its power. It seduces
the programmer, making it much easier to write bloatware. The kernel is a
critical piece of code, and must be lean and fast. We cannot afford bloat. I
think it is fair to say that it takes more skill to write efficient C++ code
than C code. Not every contributer to the linux kernel is an uber-guru, and
thus will not know the various tricks and traps for producing efficient C++
code.
</quote>


Rui Maciel

Jorgen Grahn

unread,
Jan 25, 2012, 2:44:49 PM1/25/12
to
On Wed, 2012-01-25, Pavel wrote:
> Jorgen Grahn wrote:
>> On Sun, 2012-01-22, Pavel wrote:
>> ...
>>> I guess, everyone's mileage varies. For a change, I am on AD side in this
>>> C-vs-C++ maintenance/reviewing issue although for different reasons. Reading C++
>>> code takes, in my experience, much longer time than C code of equivalent
>>> complexity because there are on average more (commonly used) meanings for
>>> identically-looking C++ code than C code. I have already given on this group an
>>> example that, in C, you pretty much know that f(a) does not change a -- but not
>>> in C++.
>>
>> I don't see the problem. You review f(A&), and immediately see that it
>> can modify its apparent argument. So you ask yourself "will this be
>> obvious in the calling code, based on the name of f and so on?" If the
>> answer is "no", you fail the code.

> Even letting alone that failing all such code you encounter prevents you from
> staying on schedule:
>
> If you do not review but maintain it as in OP case -- what do you do then?

I commented only on your claims about the difficulty of reviewing C++
code (and I seem to have missed that you talked about "reviewing and
maintenance").

I still don't see your argument about reviewing though. If it really
was "it's hard to usefully review changes in code which is already
unreadable" then that's trivially true in any language.

(I decline to discuss the "maintenance" part, not because I agree with
you but because I cannot come up with brief, good arguments at the
moment.)

...
>>> (last time I counted, operator<< had some 3 to 4 thousands overloads in my
>>> organization; add to this potential automatic conversions and you get the picture).
>>
>> And how many of these were not on the form ostream<< const T& ?
> More than a half. People create other classes than standard streams, most of
> them having stream-like (but not quite) semantics, for example for IPC purpose,
> some with different semantics.

That's a bit unusual, and I don't think I would like it.

> An example of the issue is that something like
> somestream << "abc" can lead to very different serializations for different
> types of the stream depending on whether there is an operator<< with const char
> * or some conversion is to be called.

You mentioned these conversions in your earlier posting, too. If you
have a lot those, you have my sympathies. My basic assumption is that
a Foo::Foo(T) which isn't marked 'explicit' is broken. Same with
function overloads with very similar types.

Ian Collins

unread,
Jan 25, 2012, 2:56:31 PM1/25/12
to
On 01/25/12 04:48 PM, Pavel wrote:
> Jorgen Grahn wrote:
>> On Sun, 2012-01-22, Pavel wrote:
>> ...
>>> I guess, everyone's mileage varies. For a change, I am on AD side in this
>>> C-vs-C++ maintenance/reviewing issue although for different reasons. Reading C++
>>> code takes, in my experience, much longer time than C code of equivalent
>>> complexity because there are on average more (commonly used) meanings for
>>> identically-looking C++ code than C code. I have already given on this group an
>>> example that, in C, you pretty much know that f(a) does not change a -- but not
>>> in C++.
>>
>> I don't see the problem. You review f(A&), and immediately see that it
>> can modify its apparent argument. So you ask yourself "will this be
>> obvious in the calling code, based on the name of f and so on?" If the
>> answer is "no", you fail the code.

> Even letting alone that failing all such code you encounter prevents you from
> staying on schedule:

It sounds to me like you have a process problem rather than a language
one. I don't thank anyone can do a thorough job of reviewing anything
other than small sections of unfamiliar code without the involvement of
the authour or someone else familiar with the code.

--
Ian Collins

88888 Dihedral

unread,
Jan 26, 2012, 2:04:48 AM1/26/12
to
Programming in C++ code costs more to maintain. Maybe this is good for offering
more programming positions for the employees. Also problems in C are inherited
in C++ such as the non-closure integer arithmetics and the lousy sort trap
and the famous non-checking for array boundaries in any read/write.
The vetctor part just covers up some traps but it slows down as expected.
The operator reloading and the copy constructor part of derived classes introduce
more problems in any operation that needs a new object in the RHS to be
assigned to the LHS. Of course there are people using C++ without deriving
new classses and just use those libraries in trivial programs.
Then in this cas C++ is easy to mantain.

Jorgen Grahn

unread,
Jan 26, 2012, 4:44:11 AM1/26/12
to
On Wed, 2012-01-25, Rui Maciel wrote:
> AD wrote:
...
>> linux kernel developers at one point tried (and failed),
>> primirily because of the buggy g++ frontend to gcc
>> and you can really count on your palm c++ compilers that work okay.
...

> Having said that, I'll point out what they state regarding the C++
> programming language:
>
> <quote>
> My personal view is that C++ has its merits, and makes object-oriented
> programming easier. However, it is a more complex language and is less
> mature than C. The greatest danger with C++ is in fact its power. It seduces
> the programmer, making it much easier to write bloatware. The kernel is a
> critical piece of code, and must be lean and fast. We cannot afford bloat. I
> think it is fair to say that it takes more skill to write efficient C++ code
> than C code. Not every contributer to the linux kernel is an uber-guru, and
> thus will not know the various tricks and traps for producing efficient C++
> code.
> </quote>

That's what the LKLM FAQ maintainer wrote. When /Linus/ writes about
C++, he sounds almost exactly like "AD". That's probably the the first
thing that prevents C++ in the Linux kernel.

Rui Maciel

unread,
Jan 26, 2012, 5:36:24 AM1/26/12
to
Jorgen Grahn wrote:

> That's what the LKLM FAQ maintainer wrote. When Linus writes about
> C++, he sounds almost exactly like "AD". That's probably the the first
> thing that prevents C++ in the Linux kernel.

You can read for yourself what Linus Torvalds had to say about C++:

http://lkml.org/lkml/2004/1/20/20


And again, it was about using C++ on kernel code, not C++ in general.


Rui Maciel

Nick Keighley

unread,
Jan 26, 2012, 6:24:11 AM1/26/12
to
On Jan 26, 7:04 am, 88888 Dihedral <dihedral88...@googlemail.com>
wrote:

> Programming in C++ code costs more to maintain.

I've seen some pretty nasty C

> Maybe this is good for offering
> more programming positions for the employees. Also problems in C are inherited
> in C++ such as the non-closure integer arithmetics and the lousy sort trap

the what?

> and the famous non-checking for array boundaries in any read/write.
> The vetctor part just covers up some traps but it slows down as expected.

what language avoids this? If you do array bound checking it costs. If
you don't then you run a risk. Are there languages that can prove
array bounds won't be breeched?

> The operator reloading and the copy constructor  part of derived classes introduce
> more problems  in any operation that needs a new object in the RHS to be
> assigned to the LHS.

could you expand on that; I didn't quite follow you. I don't recall
encountering a problem in this area.

> Of course there are people using C++ without deriving
> new classses and just use those libraries in trivial programs.
> Then in this cas C++ is easy to mantain.

...and isn't really C++

Nick Keighley

unread,
Jan 26, 2012, 6:25:55 AM1/26/12
to
On Jan 24, 5:21 pm, "Gernot Frisch" <m...@privacy.net> wrote:
> > I could not possibly see how it can be used to write robust code
>
> Am I feeding a troll now? :S
>
> You can write perfectly robust code in C++ if you don't use pointers at all.
> There's usually no need to do this, as other languages don't even have them.

how do I build complex structures? Eg.trees. How do I do runtime
polymorphism?

> Use references if you pass byref, and use containers if you want to allocate
> to be safe.

Containers of pointers?

Juha Nieminen

unread,
Jan 26, 2012, 11:30:58 AM1/26/12
to
Rui Maciel <rui.m...@gmail.com> wrote:
> <quote>
> My personal view is that C++ has its merits, and makes object-oriented
> programming easier. However, it is a more complex language and is less
> mature than C. The greatest danger with C++ is in fact its power. It seduces
> the programmer, making it much easier to write bloatware. The kernel is a
> critical piece of code, and must be lean and fast. We cannot afford bloat. I
> think it is fair to say that it takes more skill to write efficient C++ code
> than C code. Not every contributer to the linux kernel is an uber-guru, and
> thus will not know the various tricks and traps for producing efficient C++
> code.
> </quote>

One of the most common misconceptions among advocate C hackers is that
programming in C somehow automatically makes your program more efficient
and have "less bloat" than, for example, when programming C++, which
requires more care to be as efficient and small. (And I'm discounting
here the bunch that believes that C++ *always* produces less efficient
and larger code than C.)

Linus Torvalds, in addition to that, also has this completely weird
notion that programming in C also automatically makes your code easier
to understand and maintain (while C++ is the exact opposite).

Of course practical examples tell a completely different story. There
are plenty of C programs out there that are absolutely horrendous,
inefficient, and almost completely impossible to maintain. And many of
these are not just some obscure one-man projects, but large and popular
ones. (For example much of mplayer was like this last time I checked.
Granted, this was many years ago, so it's theoretically possible that
they have done a complete refactoring of the entire code. I find it
unlikely, though.)

That's not to say that you cannot create horrendous programs in C++.
Of course you can. And probably over half of the C++ programs out there
are horrendous. OTOH, also probably over half of C programs out there
are likewise horrendous.

The difference is, however, that C++ offers you tools that C doesn't,
tools to make your code safer and easier to understand and maintain, while
still being as efficient as an equivalent C program would.

Scott Lurndal

unread,
Jan 26, 2012, 2:13:49 PM1/26/12
to
Nick Keighley <nick_keigh...@hotmail.com> writes:
>On Jan 26, 7:04=A0am, 88888 Dihedral <dihedral88...@googlemail.com>
>wrote:
>
>> Programming in C++ code costs more to maintain.
>
>I've seen some pretty nasty C
>
>> Maybe this is good for offering
>> more programming positions for the employees. Also problems in C are inhe=
>rited
>> in C++ such as the non-closure integer arithmetics and the lousy sort tra=
>p
>
>the what?
>
>> and the famous non-checking for array boundaries in any read/write.
>> The vetctor part just covers up some traps but it slows down as expected.
>
>what language avoids this? If you do array bound checking it costs. If
>you don't then you run a risk. Are there languages that can prove
>array bounds won't be breeched?

Sure. ALGOL on various Unisys boxen, for instance.

There are still in existence processor architectures that bounds-check
each and every array reference (e.g. capability-based stack architectures such
as the Burroughs Large Systems/Unisys A-series/Clearpath).

On the other hand, the x86 'BOUND instruction was removed from the instruction
set by AMD when they developed the 64-bit extensions.

scott

Scott Lurndal

unread,
Jan 26, 2012, 2:18:45 PM1/26/12
to
Rui Maciel <rui.m...@gmail.com> writes:
>Jorgen Grahn wrote:
>
>> That's what the LKLM FAQ maintainer wrote. When Linus writes about
>> C++, he sounds almost exactly like "AD". That's probably the the first
>> thing that prevents C++ in the Linux kernel.
>
>You can read for yourself what Linus Torvalds had to say about C++:
>
>http://lkml.org/lkml/2004/1/20/20
>

He misses the point, in that article. I disagreed with him then, and
still do now.

Just because C++ has a feature (e.g. exceptions), doesn't mean you have
to use it. Having written two operating systems and a hypervisor in
a dialect of C++ (no exceptions, no run-time typing, no templates), the features
you can use (data encapsulation using classes) are quite useful.

He seems to miss the fact that one can overload not only the new operator on
a per-class basis, but indeed, can overload it on a global basis in a kernel.

scott

Scott Lurndal

unread,
Jan 26, 2012, 2:24:24 PM1/26/12
to
Juha Nieminen <nos...@thanks.invalid> writes:

> That's not to say that you cannot create horrendous programs in C++.
>Of course you can. And probably over half of the C++ programs out there
>are horrendous. OTOH, also probably over half of C programs out there
>are likewise horrendous.

The readability of C++ seems to get worse with each new version of the
standard. Once the <XXX> elements (static/dynamic casts, templates) were added
to the language, it became worse than perl for readability.

Java has a similar problem; after 1.5, they just started adding language elements
willy-nilly (but at least the syntax isn't quite so obtuse as the C++ stuff).

C++ prior to templates (Version 2.1, granted much closer to C) can be quite elegent.

And, of course, readability is in the eye of the beholder :-)

scott

Cholo Lennon

unread,
Jan 26, 2012, 3:13:52 PM1/26/12
to
On 26/01/2012 16:24, Scott Lurndal wrote:
> The readability of C++ seems to get worse with each new version of the
> standard. Once the<XXX> elements (static/dynamic casts, templates) were added
> to the language, it became worse than perl for readability.

Really? Do you think C++ cast operators go against readability? For me
is the opposite: At glance, for example, they give you more information
than the traditional C cast and, as a result, they are (IMHO) more readable.

--
Cholo Lennon
Bs.As.
ARG

Jorgen Grahn

unread,
Jan 26, 2012, 3:42:59 PM1/26/12
to
On Thu, 2012-01-26, Rui Maciel wrote:
> Jorgen Grahn wrote:
>
>> That's what the LKLM FAQ maintainer wrote. When Linus writes about
>> C++, he sounds almost exactly like "AD". That's probably the the first
>> thing that prevents C++ in the Linux kernel.
>
> You can read for yourself what Linus Torvalds had to say about C++:
>
> http://lkml.org/lkml/2004/1/20/20

I did; it was quoted in the LKML FAQ. If it's supposed to disprove
what I wrote, I fail to see how.

Scott Lurndal

unread,
Jan 26, 2012, 3:55:15 PM1/26/12
to
Buenas,

I think they may provide better _maintainability_ at the expense of _readability_.

It may also be that for someone coming from a C background (starting in 1978),
the dynamic/static cast syntax just looks alien and out of place.

Templates and exceptions on the other hand, have a distinct impact on code size
(thus icache footprint, thus performance).

Could be worse, I suppose (see below)

scott

004400 PROGRAM-ID. ENV
004500 ENVT01. ENV
004600* WHERE T = TEST SYSTEM NUMBER. ENV
004700 AUTHOR. ENV
004900 ADC-DPS N0044
005000 ATLANTA. ENV
005100 DATE-COMPILED. ENV
005200 ENVIRONMENT DIVISION. ENV
005300 CONFIGURATION SECTION. ENV
005400 SOURCE-COMPUTER. ENV
005500 NOT-DOCUMENTED. N0221
005600 OBJECT-COMPUTER. ENV
005700 V-300, N4556
005800 STACK SIZE IS 1, ENV
005900 SEGMENT-LIMIT IS 1. ENV
006000/ ENV
006100 INPUT-OUTPUT SECTION. ENV
006200 FILE-CONTROL.
...
822000 VALIDATE-ADVICE-LOOP. N1812
822100 IF NOT-KEY NOT = 0 N1812
822200 PERFORM SEND-NOTICE THRU SEND-NOTICE-EXIT. N1812
822300 PERFORM RECEIVE-SCREEN THRU RECEIVE-SCREEN-EXIT. N1812
822400 MOVE Y TO POSITION-CURSOR. N1812
822500 IF S216-CUST-DR-RT NOT NUMERIC N1812
822600 MOVE 19 TO NOT-KEY N1812
822700 MOVE ERROR-CHAR TO S216-CUST-DR-RT N1812
822800 GO TO VALIDATE-ADVICE-LOOP. N1812
822900 IF S216-CUST-DR-TC NOT NUMERIC N1812
823000 MOVE 19 TO NOT-KEY N1812
823100 MOVE ERROR-CHAR TO S216-CUST-DR-TC N1812
823200 GO TO VALIDATE-ADVICE-LOOP. N1812

Jorgen Grahn

unread,
Jan 26, 2012, 5:08:49 PM1/26/12
to
On Thu, 2012-01-26, Scott Lurndal wrote:
> Cholo Lennon <cholo...@hotmail.com> writes:
>>On 26/01/2012 16:24, Scott Lurndal wrote:
>>> The readability of C++ seems to get worse with each new version of the
>>> standard. Once the<XXX> elements (static/dynamic casts, templates)
>>> were added
>>> to the language, it became worse than perl for readability.
>>
>>Really? Do you think C++ cast operators go against readability? For me
>>is the opposite: At glance, for example, they give you more information
>>than the traditional C cast and, as a result, they are (IMHO) more readable.
>
> I think they may provide better _maintainability_ at the expense of
> _readability_.

Keep in mind, both of you, that the best way to deal with casting is
to avoid doing it! Or isolating it to a few places. C++ provides
better tools for that than C.

...
> Templates and exceptions on the other hand, have a distinct impact
> on code size (thus icache footprint, thus performance).

I can't comment on exceptions, but how do templates, in general,
increase code size? Note that templates do not imply function
inlining.

Scott Lurndal

unread,
Jan 26, 2012, 7:32:16 PM1/26/12
to
With g++, each specialization of a template results in replication of each
referenced non-inline member function. So for each unique <type>::member_function,
a separate body of code will generated. For only one or two specializations, it
may not be a significant performance impact, but consider a template for a linked
list, which is specialized by several hundred different types in an operating system;
the amount of added code can be considerable.

While not typesafe, a simple double-linked list base class from which all those
types derive, is much more efficient from a icache footprint standpoint and fairly
simple iterators can be built to iterate over the list (using casts). In this case
efficiency wins for OS and hypervisor implementations where every page used by the
OS can't be given to the application or guest.


s

Brian Drummond

unread,
Jan 26, 2012, 7:12:38 PM1/26/12
to
On Thu, 26 Jan 2012 03:24:11 -0800, Nick Keighley wrote:

> On Jan 26, 7:04 am, 88888 Dihedral <dihedral88...@googlemail.com> wrote:
>
>> Programming in C++ code costs more to maintain.
>
> I've seen some pretty nasty C

They are both pretty bad.

>> and the famous non-checking for array boundaries in any read/write. The
>> vetctor part just covers up some traps but it slows down as expected.
>
> what language avoids this? If you do array bound checking it costs. If
> you don't then you run a risk. Are there languages that can prove array
> bounds won't be breeched?

There certainly are.
But array bound checks rarely cost anything. If your compiler can't prove
and eliminate the bulk of them at compile time, get a better compiler.
Help it by defining a new integer type restricted to the size of the
array (even where the array size is only known at runtime) and using that
type for the index.
The remaining few checks cost, but you would have to write the same
checks by hand in C, so they don't cost extra, they just save programmer
time.

Anyone with even a little sympathy for "AD"'s position, or interest in
writing readable, maintainable, safe code would find it worthwhile to try
Ada 2005. It's available in any decent gcc installation.

Where you really need to eliminate all run time checks and prove all
bounds at or before compile time, use SPARK instead.

This is off topic on c.l.c++ but you did ask.

- Brian

MikeWhy

unread,
Jan 26, 2012, 11:44:01 PM1/26/12
to

"Brian Drummond" <br...@shapes.demon.co.uk> wrote in message
news:jfsq5m$q7i$1...@dont-email.me...
> On Thu, 26 Jan 2012 03:24:11 -0800, Nick Keighley wrote:
>
>> On Jan 26, 7:04Â am, 88888 Dihedral <dihedral88...@googlemail.com> wrote:
>>
>>> Programming in C++ code costs more to maintain.
>>
>> I've seen some pretty nasty C
>
> They are both pretty bad.
>
>>> and the famous non-checking for array boundaries in any read/write. The
>>> vetctor part just covers up some traps but it slows down as expected.
>>
>> what language avoids this? If you do array bound checking it costs. If
>> you don't then you run a risk. Are there languages that can prove array
>> bounds won't be breeched?
>
> There certainly are.
> But array bound checks rarely cost anything. If your compiler can't prove
> and eliminate the bulk of them at compile time, get a better compiler.
> Help it by defining a new integer type restricted to the size of the
> array (even where the array size is only known at runtime) and using that
> type for the index.
> The remaining few checks cost, but you would have to write the same
> checks by hand in C, so they don't cost extra, they just save programmer
> time.

template <typename DataT, size_t LenT>
void Foo(DataT (& foo)[LenT])
{
...
}

> Anyone with even a little sympathy for "AD"'s position, or interest in
> writing readable, maintainable, safe code would find it worthwhile to try
> Ada 2005.

Surely, this is even more absurd than the OP claim. ;)



Ian Collins

unread,
Jan 27, 2012, 2:18:21 AM1/27/12
to
On 01/27/12 09:55 AM, Scott Lurndal wrote:
> Cholo Lennon<cholo...@hotmail.com> writes:
>> On 26/01/2012 16:24, Scott Lurndal wrote:
>>> The readability of C++ seems to get worse with each new version of the
>>> standard. Once the<XXX> elements (static/dynamic casts, templates) were added
>>> to the language, it became worse than perl for readability.
>>
>> Really? Do you think C++ cast operators go against readability? For me
>> is the opposite: At glance, for example, they give you more information
>> than the traditional C cast and, as a result, they are (IMHO) more readable.
>>
>
> Buenas,
>
> I think they may provide better _maintainability_ at the expense of _readability_.
>
> It may also be that for someone coming from a C background (starting in 1978),
> the dynamic/static cast syntax just looks alien and out of place.
>
> Templates and exceptions on the other hand, have a distinct impact on code size
> (thus icache footprint, thus performance).

The only performance impact I have ever measured from the use of
exceptions is improvement. I have been testing compilers since the mid
90s and I have only found one compiler/platform (that compiler refused
to inline any function that could throw) where exceptions had a
detrimental impact on performance.

In overall performance terms, templates are no worse and often a
significant improvement over the direct C equivalent (macros) because
they aren't necessary inlined. They can also provide significant
performance improvements over another C alternative, the use of void*
and function pointers (sorting being the classic example).

Yes you can end up with multiple instances of class methods, but that is
the price you pay for type safety. Anyway, what proportion of a decent
sized project would that represent? For containers of pointers one can
easily use inline wrappers round a container of void* to avoid bloat
while retaining type safety. In most code I have seen, containers of T*
are more numerous than containers of T

Thus with contemporary tools, the twin myths of exception performance
and template code bloat are just that: myths.

--
Ian Collins

Miles Bader

unread,
Jan 27, 2012, 4:09:07 AM1/27/12
to
Ian Collins <ian-...@hotmail.com> writes:
> The only performance impact I have ever measured from the use of
> exceptions is improvement. I have been testing compilers since the mid
> 90s and I have only found one compiler/platform (that compiler refused
> to inline any function that could throw) where exceptions had a
> detrimental impact on performance.

Yeah, generally exceptions are very cheap these days, probably cheaper
than equivalently-safe explicit-return-value-checking code. I guess
some of the people decrying them may be remembering some of the
initial naive implementations using setjmp/longjmp (OK, I guess the
exception handling in MS's 32-bit ABI is still kinda of stinky).

> Yes you can end up with multiple instances of class methods, but that is
> the price you pay for type safety. Anyway, what proportion of a decent
> sized project would that represent? For containers of pointers one can
> easily use inline wrappers round a container of void* to avoid bloat
> while retaining type safety. In most code I have seen, containers of T*
> are more numerous than containers of T

Also note that for really equivalent template expansions, one can
sometimes merge the resulting redundant functions at link-time.
In gcc, for instance, using "-ffunction-sections" at compile-time, and
"-Wl,--icf=safe" at link-time; I'm pretty sure MS's compilers have
something equivalent.

-Miles

--
Love is a snowmobile racing across the tundra. Suddenly it flips over,
pinning you underneath. At night the ice weasels come. --Nietzsche

Scott Lurndal

unread,
Jan 27, 2012, 3:16:45 PM1/27/12
to
Unless you are writing an operating system or hypervisor where every byte
counts.

scott

Scott Lurndal

unread,
Jan 27, 2012, 3:29:46 PM1/27/12
to
Miles Bader <mi...@gnu.org> writes:
>Ian Collins <ian-...@hotmail.com> writes:
>> The only performance impact I have ever measured from the use of
>> exceptions is improvement. I have been testing compilers since the mid
>> 90s and I have only found one compiler/platform (that compiler refused
>> to inline any function that could throw) where exceptions had a
>> detrimental impact on performance.
>
>Yeah, generally exceptions are very cheap these days, probably cheaper
>than equivalently-safe explicit-return-value-checking code. I guess
>some of the people decrying them may be remembering some of the
>initial naive implementations using setjmp/longjmp (OK, I guess the
>exception handling in MS's 32-bit ABI is still kinda of stinky).


I tried substituting a 'new uint8[xx}' call to replace a malloc with a try
catch block for bad_alloc. I then disassembled the code. One instruction
(to test the return value of the malloc) turned into:

try {
buf = new uint8[bufsize];
7327: 4c 89 f7 mov %r14,%rdi
732a: e8 f9 e0 ff ff callq 5428 <operator new[](unsigned long)@plt>
732f: 48 89 c5 mov %rax,%rbp
7332: 49 89 c5 mov %rax,%r13
} catch (std::exception x) {
iocb->set_rd(IOT_WITH_EXCEPTIONS, RD1_OCS_MPU_PARITY);
return false;
}

switch (cmd) {
7335: 45 84 e4 test %r12b,%r12b
7338: 0f 84 8f 00 00 00 je 73cd <c_uniline_dlp::echo(c_iocb*)+0xdf>
733e: 41 80 fc 08 cmp $0x8,%r12b
7342: 0f 85 7e 01 00 00 jne 74c6 <c_uniline_dlp::echo(c_iocb*)+0x1d8>
7348: e9 21 01 00 00 jmpq 746e <c_uniline_dlp::echo(c_iocb*)+0x180>
734d: 48 89 c5 mov %rax,%rbp
7350: 48 83 fa 01 cmp $0x1,%rdx
7354: 74 08 je 735e <c_uniline_dlp::echo(c_iocb*)+0x70>
7356: 48 89 c7 mov %rax,%rdi
7359: e8 aa de ff ff callq 5208 <_Unwind_Resume@plt>
uint8 *buf;
uint8 cmd = iocb->get_op_var2();

try {
buf = new uint8[bufsize];
} catch (std::exception x) {
735e: 48 89 c7 mov %rax,%rdi
7361: e8 b2 dc ff ff callq 5018 <__cxa_get_exception_ptr@plt>
* library, and by certain language expressions. You are free to derive
* your own %exception classes, or use a different hierarchy, or to
* throw non-class data (e.g., fundamental types).
*/
class exception
{
7366: 48 8b 05 7b 83 20 00 mov 0x20837b(%rip),%rax # 20f6e8 <_DYNAMIC+0x1c0>
736d: 48 8d 40 10 lea 0x10(%rax),%rax
7371: 48 89 04 24 mov %rax,(%rsp)
7375: 48 89 ef mov %rbp,%rdi
7378: e8 db e0 ff ff callq 5458 <__cxa_begin_catch@plt>
iocb->set_rd(IOT_WITH_EXCEPTIONS, RD1_OCS_MPU_PARITY);
737d: 41 b9 00 00 00 00 mov $0x0,%r9d
7383: 41 b8 00 00 00 00 mov $0x0,%r8d
7389: b9 00 00 00 00 mov $0x0,%ecx
738e: ba 04 00 00 00 mov $0x4,%edx
7393: be 00 c0 00 00 mov $0xc000,%esi
7398: 48 89 df mov %rbx,%rdi
739b: e8 e8 dd ff ff callq 5188 <c_iocb::set_rd(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long)@plt>
uint8 *buf;
uint8 cmd = iocb->get_op_var2();

try {
buf = new uint8[bufsize];
} catch (std::exception x) {
73a0: 48 89 e7 mov %rsp,%rdi
73a3: e8 30 e1 ff ff callq 54d8 <std::exception::~exception()@plt>
73a8: e8 7b dd ff ff callq 5128 <__cxa_end_catch@plt>
73ad: 0f 1f 00 nopl (%rax)
73b0: e9 41 01 00 00 jmpq 74f6 <c_uniline_dlp::echo(c_iocb*)+0x208>
73b5: 48 89 c5 mov %rax,%rbp
73b8: 48 89 e7 mov %rsp,%rdi
73bb: e8 18 e1 ff ff callq 54d8 <std::exception::~exception()@plt>
73c0: e8 63 dd ff ff callq 5128 <__cxa_end_catch@plt>
73c5: 48 89 ef mov %rbp,%rdi
73c8: e8 3b de ff ff callq 5208 <_Unwind_Resume@plt>
return false;
}

switch (cmd) {

versus (with malloc):

buf = (uint8 *)malloc(bufsize);
7136: 4c 89 ef mov %r13,%rdi
7139: e8 6a dd ff ff callq 4ea8 <malloc@plt>
713e: 48 89 c3 mov %rax,%rbx
7141: 49 89 c6 mov %rax,%r14
if (buf == NULL) {
7144: 48 85 c0 test %rax,%rax
7147: 75 28 jne 7171 <c_uniline_dlp::echo(c_iocb*)+0x73>
iocb->set_rd(IOT_WITH_EXCEPTIONS, RD1_OCS_MPU_PARITY);
7149: 41 b9 00 00 00 00 mov $0x0,%r9d
714f: 41 b8 00 00 00 00 mov $0x0,%r8d
7155: b9 00 00 00 00 mov $0x0,%ecx
715a: ba 04 00 00 00 mov $0x4,%edx
715f: be 00 c0 00 00 mov $0xc000,%esi
7164: 48 89 ef mov %rbp,%rdi
7167: e8 4c de ff ff callq 4fb8 <c_iocb::set_rd(unsigned long, unsigned long, unsigned long, unsigned long, unsigned long)@plt>
return false;
716c: e9 40 01 00 00 jmpq 72b1 <c_uniline_dlp::echo(c_iocb*)+0x1b3>
}

switch (cmd) {

scott

Ian Collins

unread,
Jan 27, 2012, 4:01:50 PM1/27/12
to
A large proportion of my work is in embedded devices, where the byte
count is even more important!

These days of low cost, plentiful RAM, the most important factor in
hypervisor or operating system is performance, not code size.

As I said above, if code size is an an issue, there are well known
coding practices that can be employed to minimise it.

There are also techniques used by embedded tool chains to minimise code
size. However more often than not these techniques are detrimental to
performance and should only be employed when physical resources are tight.

--
Ian Collins

Ian Collins

unread,
Jan 27, 2012, 4:06:36 PM1/27/12
to
On 01/28/12 09:29 AM, Scott Lurndal wrote:
> Miles Bader<mi...@gnu.org> writes:
>> Ian Collins<ian-...@hotmail.com> writes:
>>> The only performance impact I have ever measured from the use of
>>> exceptions is improvement. I have been testing compilers since the mid
>>> 90s and I have only found one compiler/platform (that compiler refused
>>> to inline any function that could throw) where exceptions had a
>>> detrimental impact on performance.
>>
>> Yeah, generally exceptions are very cheap these days, probably cheaper
>> than equivalently-safe explicit-return-value-checking code. I guess
>> some of the people decrying them may be remembering some of the
>> initial naive implementations using setjmp/longjmp (OK, I guess the
>> exception handling in MS's 32-bit ABI is still kinda of stinky).
>
>
> I tried substituting a 'new uint8[xx}' call to replace a malloc with a try
> catch block for bad_alloc. I then disassembled the code. One instruction
> (to test the return value of the malloc) turned into:
>

How comes one version has multiple calls to new and the other one call
to malloc?

What was the original source?

--
Ian Collins

Scott Lurndal

unread,
Jan 27, 2012, 4:26:23 PM1/27/12
to
uint8 cmd = iocb->get_op_var2();

buf = (uint8 *)malloc(bufsize);
if (buf == NULL) {
iocb->set_rd(IOT_WITH_EXCEPTIONS, RD1_OCS_MPU_PARITY);
return false;
}

switch (cmd) {

vs.

uint8 cmd = iocb->get_op_var2();

try {
buf = new uint8[bufsize];
} catch (std::exception e) {
iocb->set_rd(IOT_WITH_EXCEPTIONS, RD1_OCS_MPU_PARITY);
return false;
}

switch (cmd) {


There is only one call to operator new (at 732a), the source code
is intermixed with the assembler by the 'objdump' utility and it replicated the source
line in multiple places.

scott

Cholo Lennon

unread,
Jan 27, 2012, 4:28:46 PM1/27/12
to
On 26/01/2012 19:08, Jorgen Grahn wrote:
> Keep in mind, both of you, that the best way to deal with casting is
> to avoid doing it! Or isolating it to a few places. C++ provides
> better tools for that than C.
>

I agree, of course, but when you have to deal with legacy C or low level
code casting appears (and I have to say that there is a lot of legacy C
code)

Ian Collins

unread,
Jan 27, 2012, 6:22:07 PM1/27/12
to
On 01/28/12 10:26 AM, Scott Lurndal wrote:
> Ian Collins<ian-...@hotmail.com> writes:
>> On 01/28/12 09:29 AM, Scott Lurndal wrote:
>>>
>>>
>>> I tried substituting a 'new uint8[xx}' call to replace a malloc with a try
>>> catch block for bad_alloc. I then disassembled the code. One instruction
>>> (to test the return value of the malloc) turned into:
>>>
>>
>> How comes one version has multiple calls to new and the other one call
>> to malloc?
>>
>> What was the original source?
>>
>
> uint8 cmd = iocb->get_op_var2();
>
> buf = (uint8 *)malloc(bufsize);
> if (buf == NULL) {
> iocb->set_rd(IOT_WITH_EXCEPTIONS, RD1_OCS_MPU_PARITY);
> return false;
> }
>
> switch (cmd) {
>
> vs.
>
> uint8 cmd = iocb->get_op_var2();
>
> try {
> buf = new uint8[bufsize];
> } catch (std::exception e) {

never catch exceptions by value, always catch by const reference to
avoid slicing.

> iocb->set_rd(IOT_WITH_EXCEPTIONS, RD1_OCS_MPU_PARITY);
> return false;
> }
>
> switch (cmd) {
>
> There is only one call to operator new (at 732a), the source code
> is intermixed with the assembler by the 'objdump' utility and it replicated the source
> line in multiple places.

This is fairly atypical use of exceptions, mixing exceptions and return
codes. It is more common to catch the exception at a higher call. This
simplifies the source and machine code (fewer conditional branches).

The catch is also the reason for all the extra code, constructing and
destructing a temporary std::exception object. The actual exception
handling part of the code is this bit:

} catch (std::exception x) {
73a0: 48 89 e7 mov %rsp,%rdi
73a3: e8 30 e1 ff ff callq 54d8
<std::exception::~exception()@plt>
73a8: e8 7b dd ff ff callq 5128 <__cxa_end_catch@plt>
73ad: 0f 1f 00 nopl (%rax)
73b0: e9 41 01 00 00 jmpq 74f6
<c_uniline_dlp::echo(c_iocb*)+0x208>
73b5: 48 89 c5 mov %rax,%rbp
73b8: 48 89 e7 mov %rsp,%rdi
73bb: e8 18 e1 ff ff callq 54d8
<std::exception::~exception()@plt>
73c0: e8 63 dd ff ff callq 5128 <__cxa_end_catch@plt>
73c5: 48 89 ef mov %rbp,%rdi
73c8: e8 3b de ff ff callq 5208 <_Unwind_Resume@plt>
return false;
}

hardly bloat! Now if the exception is caught higher up the call chain
(with f() being a void function), there would be less, rather than more
code.

--
Ian Collins

Scott Lurndal

unread,
Jan 27, 2012, 11:18:30 PM1/27/12
to
Ian Collins <ian-...@hotmail.com> writes:
>On 01/28/12 10:26 AM, Scott Lurndal wrote:
>> Ian Collins<ian-...@hotmail.com> writes:
>>> On 01/28/12 09:29 AM, Scott Lurndal wrote:
>>>>
>>>>
>>>> I tried substituting a 'new uint8[xx}' call to replace a malloc with a try
>>>> catch block for bad_alloc. I then disassembled the code. One instruction
>>>> (to test the return value of the malloc) turned into:
>>>>
>>>
>>> How comes one version has multiple calls to new and the other one call
>>> to malloc?
>>>
>>> What was the original source?
>>>
>>
>> uint8 cmd = iocb->get_op_var2();
>>
>> buf = (uint8 *)malloc(bufsize);
>> if (buf == NULL) {
>> iocb->set_rd(IOT_WITH_EXCEPTIONS, RD1_OCS_MPU_PARITY);
>> return false;
>> }
>>
>> switch (cmd) {
>>
>> vs.
>>
>> uint8 cmd = iocb->get_op_var2();
>>
>> try {
>> buf = new uint8[bufsize];
>> } catch (std::exception e) {
>
>never catch exceptions by value, always catch by const reference to
>avoid slicing.

Good to know, I guess. Since I intend to keep the malloc and forgo
the try/catch clause, the point is however moot.

>
>> iocb->set_rd(IOT_WITH_EXCEPTIONS, RD1_OCS_MPU_PARITY);
>> return false;
>> }
>>
>> switch (cmd) {
>>
>> There is only one call to operator new (at 732a), the source code
>> is intermixed with the assembler by the 'objdump' utility and it replicated the source
>> line in multiple places.
>
>This is fairly atypical use of exceptions, mixing exceptions and return
>codes. It is more common to catch the exception at a higher call. This
>simplifies the source and machine code (fewer conditional branches).

However, in this case (modeling a physical device), the best determination
of how to present the failure can be made as close to the cause of the
exception as possible. I would think that for most applications that
can actually recover from an error (as opposed to just catching std::exception
at the top level, printing a message, and exiting), keeping the recovery action
as close to the code that actually failed makes recovery much simpler.


>
>The catch is also the reason for all the extra code, constructing and
>destructing a temporary std::exception object. The actual exception
>handling part of the code is this bit:

Yet creating and destroying a temporary std::exception object also counts in
terms of both extra cycles and code footprint. Both of which impact
performance (generally negatively).

And indeed, some simple performance testing of code running under the simulation
(a 15,000 line BPL compile), shows that when I try exceptions in one of the common
allocation paths, the performance of the BPL compile drops from 17,177 records compiled
per minute to 16,585 records compiled per minute - an almost 4% performance degredation;
this is actually worse than I expected for a single conversion from malloc/init to
new/constructor with try/catch - I'll need to dig into this further.


>
> } catch (std::exception x) {
> 73a0: 48 89 e7 mov %rsp,%rdi
> 73a3: e8 30 e1 ff ff callq 54d8
><std::exception::~exception()@plt>
> 73a8: e8 7b dd ff ff callq 5128 <__cxa_end_catch@plt>
> 73ad: 0f 1f 00 nopl (%rax)
> 73b0: e9 41 01 00 00 jmpq 74f6
><c_uniline_dlp::echo(c_iocb*)+0x208>
> 73b5: 48 89 c5 mov %rax,%rbp
> 73b8: 48 89 e7 mov %rsp,%rdi
> 73bb: e8 18 e1 ff ff callq 54d8
><std::exception::~exception()@plt>
> 73c0: e8 63 dd ff ff callq 5128 <__cxa_end_catch@plt>
> 73c5: 48 89 ef mov %rbp,%rdi
> 73c8: e8 3b de ff ff callq 5208 <_Unwind_Resume@plt>
> return false;
> }
>
>hardly bloat! Now if the exception is caught higher up the call chain
>(with f() being a void function), there would be less, rather than more
>code.

40 bytes. more than half a cache line each occurance (and you really should
count the exception object constructor/destructors too). In some cases, it really matters.

And placing the catch higher in the call chain is not possible (at least not without
adding a large number of conditionals and carrying a great deal of state in
some derived exception class to the catch).

scott

Miles Bader

unread,
Jan 27, 2012, 11:44:31 PM1/27/12
to
sc...@slp53.sl.home (Scott Lurndal) writes:
>>The catch is also the reason for all the extra code, constructing and
>>destructing a temporary std::exception object. The actual exception
>>handling part of the code is this bit:
>
> Yet creating and destroying a temporary std::exception object also counts in
> terms of both extra cycles and code footprint. Both of which impact
> performance (generally negatively).

Er, exceptions are intended to be _exceptional_.

If some exception occurs so often that it has a measurable performance
impact, it probably shouldn't be an exception.

If you look at the code generated for the two styles, one of the big
differences with the exception-using code is that the _normal_ case
(where no exception is raised) is smaller and faster, since it can
basically proceed without considering the exceptional case. The
exception-handling code is out-of-line, to avoid a negative icache
impact.

[Also note that much "handling" of exceptions is not actually "reacting"
to specific exceptions, but simply cleaning up and propagating an error;
in C++, this typically happens via RAII (i.e. "unwind-protect" in lisp),
or "catch(...)", and those have very low space overhead, as they do not
need to do any kind of allocation/copying/matching; mostly they simply
execute the user code to do whatever is needed.]

-Miles

--
Carefully crafted initial estimates reward you not only with
reduced computational effort, but also with understanding and
increased self-esteem. -- Numerical methods in C,
Chapter 9. "Root Finding and Nonlinear Sets of Equations"

Ian Collins

unread,
Jan 28, 2012, 12:06:34 AM1/28/12
to
But it is a typical novice error that leads to false assumptions
regarding exception performance.

>>
>>> iocb->set_rd(IOT_WITH_EXCEPTIONS, RD1_OCS_MPU_PARITY);
>>> return false;
>>> }
>>>
>>> switch (cmd) {
>>>
>>> There is only one call to operator new (at 732a), the source code
>>> is intermixed with the assembler by the 'objdump' utility and it replicated the source
>>> line in multiple places.
>>
>> This is fairly atypical use of exceptions, mixing exceptions and return
>> codes. It is more common to catch the exception at a higher call. This
>> simplifies the source and machine code (fewer conditional branches).
>
> However, in this case (modeling a physical device), the best determination
> of how to present the failure can be made as close to the cause of the
> exception as possible. I would think that for most applications that
> can actually recover from an error (as opposed to just catching std::exception
> at the top level, printing a message, and exiting), keeping the recovery action
> as close to the code that actually failed makes recovery much simpler.

It may well be, but the catch and the throw my still be several calls
away. Using nested small functions is much cleaner with exceptions than
with return codes. In your example you return the state in the object
passed. An exception based design may well pass the state in an
application specific exception.

>> The catch is also the reason for all the extra code, constructing and
>> destructing a temporary std::exception object. The actual exception
>> handling part of the code is this bit:
>
> Yet creating and destroying a temporary std::exception object also counts in
> terms of both extra cycles and code footprint. Both of which impact
> performance (generally negatively).

Only if the exceptional condition occurs. The normal path of execution
will not be impacted (and will be cleaner and faster than the error
checking case).

> And indeed, some simple performance testing of code running under the simulation
> (a 15,000 line BPL compile), shows that when I try exceptions in one of the common
> allocation paths, the performance of the BPL compile drops from 17,177 records compiled
> per minute to 16,585 records compiled per minute - an almost 4% performance degredation;
> this is actually worse than I expected for a single conversion from malloc/init to
> new/constructor with try/catch - I'll need to dig into this further.

If you are mixing exceptions and return codes, you aren't really making
a fair comparison. It is very likely you could improve the performance
in other ways, such as a specialised allocator. If your application was
designed to use exceptions throughout, I bet you would see a performance
improvement.

>>
>> } catch (std::exception x) {
>> 73a0: 48 89 e7 mov %rsp,%rdi
>> 73a3: e8 30 e1 ff ff callq 54d8
>> <std::exception::~exception()@plt>
>> 73a8: e8 7b dd ff ff callq 5128<__cxa_end_catch@plt>
>> 73ad: 0f 1f 00 nopl (%rax)
>> 73b0: e9 41 01 00 00 jmpq 74f6
>> <c_uniline_dlp::echo(c_iocb*)+0x208>
>> 73b5: 48 89 c5 mov %rax,%rbp
>> 73b8: 48 89 e7 mov %rsp,%rdi
>> 73bb: e8 18 e1 ff ff callq 54d8
>> <std::exception::~exception()@plt>
>> 73c0: e8 63 dd ff ff callq 5128<__cxa_end_catch@plt>
>> 73c5: 48 89 ef mov %rbp,%rdi
>> 73c8: e8 3b de ff ff callq 5208<_Unwind_Resume@plt>
>> return false;
>> }
>>
>> hardly bloat! Now if the exception is caught higher up the call chain
>> (with f() being a void function), there would be less, rather than more
>> code.
>
> 40 bytes. more than half a cache line each occurance (and you really should
> count the exception object constructor/destructors too). In some cases, it really matters.

No I shouldn't.

It only occurred in your code because you caught by valve. No exception
object is created unless one is thrown. I also quoted more code than I
should (because of the catch by value). Change your code to catch by
const reference and you will see. For example, a bare bones example
with gcc:

bool f( X* iocb ){
try {
uint8_t* buf = new uint8_t[bufsize];
return true;
}
catch (const std::exception& e) {
return false;
}
}

compiles to (removing some labels for brevity):

pushl %ebp
movl %esp, %ebp
subl $24, %esp
movl $42, (%esp)
call _Znaj
movl $1, %eax
leave
ret
.L6:
subl $1, %edx
je .L4
movl %eax, (%esp)
call _Unwind_Resume
.L4:
movl %eax, (%esp)
call __cxa_begin_catch
call __cxa_end_catch
xorl %eax, %eax
leave
ret

> And placing the catch higher in the call chain is not possible (at least not without
> adding a large number of conditionals and carrying a great deal of state in
> some derived exception class to the catch).

The state has to be carried somewhere... If it is only required in the
case of an error, the exception is the logical place for it.

--
Ian Collins

Dombo

unread,
Jan 28, 2012, 6:59:24 AM1/28/12
to
Op 27-Jan-12 1:32, Scott Lurndal schreef:
With judicious use of templates you can have both in C++; type-safe
linked lists without code duplication using the technique explained in
the chapter about template specializations in the book "The C++
programming Language" written by Bjarne Stroustrup. Yes, with this
technique there are a few casts in the template code, but that is a hell
of a lot better than sprinkling casts all over the place.

IMO seeing a lot of casts in C++ code is a bad sign. With a good design
you rarely, if ever, need to cast. That C++ casts stand out more clearly
(and can be easily grepped) than C style cast is a good thing as far as
I am concerned.


Juha Nieminen

unread,
Jan 28, 2012, 11:00:27 AM1/28/12
to
Scott Lurndal <sc...@slp53.sl.home> wrote:
> The readability of C++ seems to get worse with each new version of the
> standard. Once the <XXX> elements (static/dynamic casts, templates) were added
> to the language, it became worse than perl for readability.

I believe you are confusing readability with brevity. Not the same
thing.

Scott Lurndal

unread,
Jan 28, 2012, 4:31:32 PM1/28/12
to
Miles Bader <mi...@gnu.org> writes:
>sc...@slp53.sl.home (Scott Lurndal) writes:
>>>The catch is also the reason for all the extra code, constructing and
>>>destructing a temporary std::exception object. The actual exception
>>>handling part of the code is this bit:
>>
>> Yet creating and destroying a temporary std::exception object also counts in
>> terms of both extra cycles and code footprint. Both of which impact
>> performance (generally negatively).
>
>Er, exceptions are intended to be _exceptional_.
>
>If some exception occurs so often that it has a measurable performance
>impact, it probably shouldn't be an exception.

The exception never occurs (i.e., I never run out of memory). It's the
added code to handle the exception and it's effect on a (very) hot codepath
that causes the 4% hit in performance. That is the only change in the
codebase, and I ran the benchmark three times with each flavor (try/catch/new
vs. malloc). I have to admit that I was surprised by the difference and I'm
going to take a look at the actual codepaths and do some profiling to see why
adding a try/catch clause has such a large effect, when the exception is never
taken.

scott

88888 Dihedral

unread,
Jan 28, 2012, 5:25:37 PM1/28/12
to
在 2012年1月26日星期四UTC+8下午7时24分11秒,Nick Keighley写道:
> On Jan 26, 7:04 am, 88888 Dihedral <dihedr...@googlemail.com>
> wrote:
>
> > Programming in C++ code costs more to maintain.
>
> I've seen some pretty nasty C
>
> > Maybe this is good for offering
> > more programming positions for the employees. Also problems in C are inherited
> > in C++ such as the non-closure integer arithmetics and the lousy sort trap
>
> the what?
>
> > and the famous non-checking for array boundaries in any read/write.
> > The vetctor part just covers up some traps but it slows down as expected.
>
> what language avoids this? If you do array bound checking it costs. If
> you don't then you run a risk. Are there languages that can prove
> array bounds won't be breeched?
>
> > The operator reloading and the copy constructor  part of derived classes introduce
> > more problems  in any operation that needs a new object in the RHS to be
> > assigned to the LHS.
>
> could you expand on that; I didn't quite follow you. I don't recall
> encountering a problem in this area.
>

I classify methods according to
A. those just modify pass in objects and use temprorary variables on the stack or static allocated buffers on the heap before invoked by messages.
This class is safe for run-time polymorphism.

B. those have to generate any new non-temporary object to be assigned to some objects in return, somewhat like the heap hog eater in this calss.
If any method in this class calls a method in this class, then it becomes a
memrory hog very easily especially in the recursive way.



> > Of course there are people using C++ without deriving
> > new classses and just use those libraries in trivial programs.
> > Then in this cas C++ is easy to mantain.
>
> ...and isn't really C++

Ian Collins

unread,
Jan 28, 2012, 5:32:57 PM1/28/12
to
How about new (without the exceptions) compared to malloc? new is doing
more work than malloc, one reason I suggested a specialised allocator.

--
Ian Collins

88888 Dihedral

unread,
Jan 28, 2012, 5:55:25 PM1/28/12
to
在 2012年1月29日星期日UTC+8上午6时32分57秒,Ian Collins写道:
Well, an object with some methods to generate new objects not to be garbage collected very soon following the o stack push-pop mechnism of auto varibles are somewaht evil in C++ if the programmer does not think carefully and write codes to chain these methods in class B arbitrarily then there might be a definitely expoenti ally growth rate of the heap used by a lousy fat programming hog in some programs.

Ian Collins

unread,
Jan 28, 2012, 5:59:38 PM1/28/12
to
On 01/29/12 11:55 AM, 88888 Dihedral wrote:
> 在 2012年1月29日星期日UTC+8上午6时32分57秒,Ian Collins写道:
>> On 01/29/12 10:31 AM, Scott Lurndal wrote:
>>> Miles Bader<mi...@gnu.org> writes:
>>>> sc...@slp53.sl.home (Scott Lurndal) writes:
>>>>>> The catch is also the reason for all the extra code, constructing and
>>>>>> destructing a temporary std::exception object. The actual exception
>>>>>> handling part of the code is this bit:
>>>>>
>>>>> Yet creating and destroying a temporary std::exception object also counts in
>>>>> terms of both extra cycles and code footprint. Both of which impact
>>>>> performance (generally negatively).
>>>>
>>>> Er, exceptions are intended to be _exceptional_.
>>>>
>>>> If some exception occurs so often that it has a measurable performance
>>>> impact, it probably shouldn't be an exception.
>>>
>>> The exception never occurs (i.e., I never run out of memory). It's the
>>> added code to handle the exception and it's effect on a (very) hot codepath
>>> that causes the 4% hit in performance. That is the only change in the
>>> codebase, and I ran the benchmark three times with each flavor (try/catch/new
>>> vs. malloc). I have to admit that I was surprised by the difference and I'm
>>> going to take a look at the actual codepaths and do some profiling to see why
>>> adding a try/catch clause has such a large effect, when the exception is never
>>> taken.
>>
>> How about new (without the exceptions) compared to malloc? new is doing
>> more work than malloc, one reason I suggested a specialised allocator.
>
> Well, an object with some methods to generate new objects not to be garbage collected very soon following the o stack push-pop mechnism of auto varibles are somewaht evil in C++ if the programmer does not think carefully and write codes to chain these methods in class B arbitrarily then there might be a definitely expoenti ally growth rate of the heap used by a lousy fat programming hog in some programs.

Do what?

--
Ian Collins

Ian Collins

unread,
Jan 28, 2012, 6:22:44 PM1/28/12
to
On 01/29/12 11:49 AM, Scott Lurndal wrote:
> Ian Collins<ian-...@hotmail.com> writes:
>> On 01/28/12 05:18 PM, Scott Lurndal wrote:
>
>>> However, in this case (modeling a physical device), the best determination
>>> of how to present the failure can be made as close to the cause of the
>>> exception as possible. I would think that for most applications that
>>> can actually recover from an error (as opposed to just catching std::exception
>>> at the top level, printing a message, and exiting), keeping the recovery action
>>> as close to the code that actually failed makes recovery much simpler.
>>
>> It may well be, but the catch and the throw my still be several calls
>> away. Using nested small functions is much cleaner with exceptions than
>> with return codes. In your example you return the state in the object
>> passed. An exception based design may well pass the state in an
>> application specific exception.
>
> Which will have additional overhead to allocate, construct,
> destroy and deallocate the application class derived from std::exception, nicht wahr?

Only in the exceptional circumstances where one is thrown. As I said,
the state has to be returned somewhere.

> I think you would find that "small nested functions" is exactly what is
> used, and in this case, the object passed doesn't necessary _return_ the state
> passed so much as provide a channel for returning the state to the final
> receipient.
>
> Now in the core processor simulation code sigsetjmp/siglongjmp are used to reset
> the simulated processor to the start of the instruction processing loop when
> an exception occurs executing an instruction (an address error, invalid instruction,
> etc). These could possibly be converted to exceptions, but I'm quite sure that
> the performance would be worse and the RAS characteristics of the application
> wouldn't change appreciably.

By using exceptions, you are able to utilise the full power of the
language, such as RAII which out of band jumps preclude.

One point I have been trying to make is bolting exceptions onto an
existing design is seldom a good idea. Neither is having to take them
out, which was a situation I once found myself in! Error handling is a
fundamental part of a system's design and mixing paradigms invariably
ends in tears.

> I remember reading Tom Cargill's article on exceptions back when they were
> introduced to the language - I think many of his points still apply - exceptions
> are not a universal panacea and careful analysis of all codepaths need be done
> to prevent memory leaks or access to deallocated data when exceptions are being
> thrown.

This is true and the language provides us with the tools to achieve
this. Tools which cannot be used with out of band jumps!

> The same caveats, of course, apply to setjmp/longjmp as well, but I
> don't need to allocate an exception object (just set one of 10 bits in a member
> field of the current 'this' when the longjmp is issued; the jmp_buf also a member
> of the current object).

The cost of constructing an exception object are far outweighed by the
cost of throwing it *in the exceptional case*.

>>>> The catch is also the reason for all the extra code, constructing and
>>>> destructing a temporary std::exception object. The actual exception
>>>> handling part of the code is this bit:
>>>
>>> Yet creating and destroying a temporary std::exception object also counts in
>>> terms of both extra cycles and code footprint. Both of which impact
>>> performance (generally negatively).
>>
>> Only if the exceptional condition occurs. The normal path of execution
>> will not be impacted (and will be cleaner and faster than the error
>> checking case).
>
> I haven't seen this in practice, but then my sole exposure to C++ code
> has been in the Operating Systems/Microkernel/Hypervisor area none of which
> used exceptions (most of which predated exceptions :-), aside from one
> application at a major internet certification authority, which also predated
> exceptions.

That's where our experiences diverge, I've been comparing the
performance of exceptions on various platforms for many years and I've
found exceptions are generally faster (always on the Unix and Linux
platforms I use). From my perspective, the exceptions vs error returns
argument was settled long ago.

> Let me be clear, I never actually took an exception in the test I described above;
> the sole difference was changing the
>
> buf = malloc(XXX); if (buf == NULL) { YYY}
>
> test to
>
> try {buf = new uint8[XXX];} catch (std::exception& e) { YYY }
>
> (and of course, the corresponding 'free()'<-> 'delete []' changes).

You have introduced two variables, exceptions and new. Try eliminating
both.

--
Ian Collins

Jorgen Grahn

unread,
Jan 29, 2012, 1:02:46 PM1/29/12
to
Yes, and I think part of what I was trying to say was: When you have a
chance to rewrite such code, it pays to first check if you can
eliminate the cast in some other way (e.g. with a wrapper function
which does the casting) rather than replace the C-style cast with the
best C++ cast.

Scott Lurndal

unread,
Jan 30, 2012, 12:08:28 PM1/30/12
to
I've tried using new (sans catch) and malloc both. The difference there is
pretty much in the noise. I've been planning on trying the gcc option -fcheck-new
with the 'new' to handle the case where new returns null (to prevent the constructor
from running) and compare that with malloc; this will add a test and
branch to the hot path, I suspect. If I use new (nothrow), will that still call
the constructor (and SIGSEGV) if the new returns NULL?

I ported a pool allocator over the weekend that can be used with an overloaded
new operator

void *operator new(size_t, c_pool *p) { return p->alloc(); }

The pool class uses ::mmap(MAP_ANONYMOUS) to get pages which are then subdivided
into appropriately sized chunks (16-byte aligned for efficiency on 64-bit
architectures).

c_pool *pool;
pool = new c_pool("Class Objects", sizeof(c_class), 100); // At init time

...

object = new (pool) c_class(); // at run time

This is highly efficient in the cases where you know a priori that you'll
never run out of pool elements (sans a coding error, of course).

A downside is you can't use delete but rather must pool->free(object).

scott

Robert Miles

unread,
Feb 26, 2012, 11:16:30 PM2/26/12
to
On 1/21/2012 6:40 AM, AD wrote:
> On Jan 18, 6:51 am, Miles Bader<mi...@gnu.org> wrote:
>> AD<isq...@gmail.com> writes:
>>>> So, you're not coding in C++, and you come to a C++ community hangout to
>>>> complain about C++ being difficult to comprehend, and you expect what,
>>>> sympathy?<shrug>
>>
>>> I'm not coding in C++ ANYMORE
>>> I could not possibly see how it can be used to write robust code
>>
>> You expect us to trust your judgement?
>>
>> [I've found C++ _much_ easier to write robust code in compared to C.
>> It is clearly no proof against incompetent coders (nothing is), but it
>> does offer some really good tools to help competent ones...]
>>
> Well, objective-c (and it's inherent to all c based languages, unless
> you start ripping out pointers, etc) is prone to allowing a single fly-
> idiot
> poisoning the whole barrel, and java like languages
> were designed precisely to keep idiots at bay, but c++ seems to be
> especially
> susceptible to providing morons with tools to automate
> writing some crap code.

Looks like you've been fired from a programming management job
for incompetence in choosing which programmers you hired, but
weren't fired fast enough to keep you from becoming familiar
with those incompetent programmers.
0 new messages