I use C++ in a pretty full sense in the kernel every day, and I
completely agree with your fundamental point - don’t abuse it and it
won’t abuse you - as well as that the opponents are certainly more
vociferous and, in my opinion, tend to be given to worst case scenarios
that may or may not exist, and in some cases just hysteria, but I can’t
say that I agree with you in some places here. Fundamentally, I am much
more interested in helping people understand the intent of source code
than the compiler; the compiler is on it’s own. In my opinion, I think
Maxim’s point here is that the NULL error is damn rare, and that some of
the issues with the semantics of references are more common, which I
would agree with, if that is in fact what he is saying. I don’t use
references much myself, except in the case of overloaded operators,
which I don’t use much either and are for all practical purposes
unusable with out them, because they do not declare the intent or lack
there of to modify an argument, whereas a pointer states that this is
the working assumption, one which is not going to be true a lot of the
time, but I prefer that problem than the one with references. It’s not
like either is a big deal, but over time, ‘->’ has been etched in to my
brain right next to ‘modify.’
I think this basic argument applies to a number of ‘C++’ features that
for probably ten years we were assured not only that they were the
‘better’ ways to do things, but, in fact, they were they only possible
way to accomplish things when scale was considered. This, of course,
was preposterous, and even a cursory look at the fates of early large
C++ projects that happened outside of Murray Hill will show a trail with
some huge, abject disasters from companies like Mentor Graphics. I
think some of the rigidity around this issue now is partially a reaction
to the past, when C++ was going to cure cancer, and it turned out that,
unless you happen to be Bjarne (not even going to give spelling his last
name a go) or Andrew Koenig, et. al., C++ is a lot harder to do well,
and a disaster waiting to happen for those who don’t treat it well, with
the irony of this being, it’s the same reaction to both sides of the
same coin. Also, some of the ‘better ways’ are very dubious when
considered from either a risk or reward point of view. For example,
using cout over printf(). Sure it’s safer, but it’s tedious as hell to
write, massacres your source code because it takes a huge amount of
space (relatively), especially when no one really cares about it or the
printf it replaced, and I’ve yet to see the program that was brought to
it’s knees because of an invalid format spec, written by anyone who has
ever gotten anything worth discussing or using out the door. Aside from
the fact that even in error, a bad printf() statement is still
essentially a debug trace that tells you where to look, if printf() is a
deal breaker for you, your fate was decided a long time ago.
As an aside, SAL is a crime against source code the world over.
Readability of source code always comes before tools in my book. Much
like the compiler, they too are own their own with me. I really like
the capabilities of PREfast, and I think that both sides of the debate
are very reasonable, but, for me, until it starts finding bugs that I
can’t find in other ways in a reasonable time frame, I’m not throwing my
code and really my obsessive habits under the bus. I like tools that do
what I want, not the other way around.
Cheers,
mm
Oliver Schneider wrote:
Anton, Maxim,
(Anton wrote:)
> So there is only one question left - do we really need all the above (and
> quite a few features beyond that) in the kernel mode???
wrong question, IMO. The question more is whether *you* or *me* or anyone else him/herself or in team needs these features or finds them useful. It seems that the opponents of C++ in KM are quicker to tell *everyone* how to do what (i.e. not use C++), than the proponents are 
(Maxim wrote:)
> For RAII code to be readable, your should declare only after {, so that
> {} will be the locked code path. Otherwise, the code reader will be
> confused a lot on what is the locked code path.
Sure.
> Correct. Now note lots of unexperienced C++ coders, who know the language
> features (including the most recent ones of 2000ies), but have no
> intuitive sense of how to do things easily.
Then educate them, if it’s in your company.
> In reality, the bug with passing a NULL pointer somewhere is the most
> uncommon bug ever met 
So? Uncommon doesn’t mean it can’t happen. And making the programmer go through hoops to make it happen, will at least get the programmer thinking (hopefully!), since it should then dawn them that this was *not* intended.
No question, references are more restrictive than pointers, but *that’s* the feature, otherwise it would be merely the clone of the functionality of pointers. References allow you to express requirements in code and the compiler will complain if the caller doesn’t comply. I thought there was a broad consensus among programmers that forcing compiler errors, where the alternative would be runtime errors (which need handling and “~5 times more code to implement”
…) was a good thing. Seems I was wrong.
People use SAL to help PREfast understand the code. Use a few (or more) well-chosen C++ features and you’ll help the *compiler* to understand your code (and intentions).
> This leads to ~5 times more code to implement the same, and to wrong
> choice of language features to implement the task (like trying to do
> polymorphic object loading from a stream using references instead of
> pointers - switching to pointers is 10 times easier then doing this with
> references which have issues with autocast in the inheritance tree).
I had something else in mind, e.g. the typical:
if(void* x = malloc(12345))
{
if(void* y = malloc(23456))
{
// do some things …
if(SomeWeirdError())
{
HandleError();
free(y);
free(x);
return -1;
}
// do some other things here
free(y);
}
free(x);
}
You can make the code more modular and readable by using RAII here with the feature that classes on stack are destroyed when going out of scope *alone*. And if the original code with malloc/free (which is the kind of C I usally encounter in .cpp files of the aforementioned kind of people) “is probably the best way of C++ use”, well then I am out of the discussion. It doesn’t make sense to argue further then, because we have fundamentally different opinions on how to use/write C++. As was stated before by others, if you don’t abuse C++, it won’t abuse you!
// Oliver