Pros n Cons of using Classes (CPP) at Kernel Level

> Can you give any reference for this?
I gave an example in the very next sentence after your quote.

Concerning Turing-completeness, your statement is just a classical example of red herring.

The concept of Turing-completeness applies to computability of a function - if some function X can be computed in some Turing-complete language A (or C), it means that this function can be computed in any other Turing-complete language. However, this is not what we speak about here, right - we are speaking about the program structure, and this is where the concept of OOP comes into the play.
.

C++ is positioned, described and advertised as an object-oriented language, while C is supposed to be procedural. However, in actuality, all the advantages that OOP offers result from your way of thinking about the problem in question, rather than from a language that you use. If you have any doubts about it, take a brief look at Linux/xBSD/Solaris kernels - you will see that, in actuality, you can easily write OO programs in plain C, and do it just fine. This is what I was talking about in my previous post…

Anton Bassov

I can give plenty of examples. In fact years ago, it was examples such as
your that started the claims of better maintainability. As I stated when
people did real studies of maintainability, either by looking at a project
over the years, or by putting together code with such samples, then having
people debug it who had not built the example all the results came out
against C++.

This was a hot topic at the C++ standards committee, and while a number of
things were done to alleviate problems I never saw a study that said it had
been solved.

Don Burn
Windows Driver Consulting
Website: http://www.windrvr.com

-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of V?ctor M. Gonz?lez
Sent: Thursday, October 20, 2016 2:38 PM
To: Windows System Software Devs Interest List
Subject: Re: [ntdev] Pros n Cons of using Classes (CPP) at Kernel Level

> Can you give any reference for this?
I gave an example in the very next sentence after your quote.


NTDEV is sponsored by OSR

Visit the list online at:
http:

MONTHLY seminars on crash dump analysis, WDF, Windows internals and software
drivers!
Details at http:

To unsubscribe, visit the List Server section of OSR Online at
http:</http:></http:></http:>

xxxxx@hotmail.com wrote:

Concerning Turing-completeness, your statement is just a classical example of red herring.

The concept of Turing-completeness applies to computability of a function - if some function X can be computed in some Turing-complete language A (or C), it means that this function can be computed in any other Turing-complete language. However, this is not what we speak about here, right

It most certainly is. You accused me of thinking “there is … nothing
in C++ that cannot be done in C,” as if that were a bad thing. That is
exactly Turing completeness. Now, maybe that’s not what you meant to
accuse me of, but that is exactly what you said.

C++ is positioned, described and advertised as an object-oriented language, while C is supposed to be procedural.

You’re making your own definitions so you can strike them down. Both of
these are procedural languages, and both of them are object-oriented.
C++ emphasizes objects more than C, and that’s why it is a better choice
for programs that focus on data, which is most programs.

However, in actuality, all the advantages that OOP offers result from your way of thinking about the problem in question, rather than from a language that you use. If you have any doubts about it, take a brief look at Linux/xBSD/Solaris kernels - you will see that, in actuality, you can easily write OO programs in plain C, and do it just fine.

Of course it’s possible to write OO programs in plain C, but I dispute
your addition of the word “easily”. My work involves almost as much
Linux as it does Windows, so I have spent a great deal of time wading
through the Linux kernel. When one does so, what becomes obvious is
how painful it is to handle lists and queues and strings. Yes, they
absolutely have facilities for managing their data structures, and
drivers use them extensively, but they are wordy, finicky, and
error-prone. C++ simply lets me express those concepts in a way that is
less prone to mistakes.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

C as an object oriented language?

It is certainly possible to write object oriented programs in C, but it is not by virtue of innate support in the language.

Very few of use here will agree on anything in this thread, but for what it is worth, Turing completeness is irrelevant; I too can write a given program more quickly in C++ than in plain C; and I agree whole heartedly that the use of C++ is a net negative on the overall productivity of any large project. In my industry, peer review is essential along with a combination of exhaustive test cases for deterministic algorithms and formal methods for provably correct code. All of these attempts to improve the quality of code can easily be undermined by the existence of language features that allow non-obvious side effects to result from seemingly simple line of code such as

A = B; // watch out for overloaded operators; this may not be a simple assignment

Or worse

If(a == b) // this is a particularly evil kind of overloaded operator that can have side effects on a, b or both

And even

Return false; // this can cause automatic object destruction that can result in the execution of lengthy sequences of code or even blocking on lock objects

I wont even attempt to cite an example of the consequences of multiple inheritance ? especially when the same base class exists more than once in the inherence tree.

The fact that these things are never used by reasonable programmers (or at least not by me) does not obviate the need to check for them when reviewing code.

Again, the more modern G3 OO languages (Java and C# are the notable examples) dispense with the worse of both ? but they are all unfit for the purpose as they require runtimes that cannot function in the Windows kernel (although it might be possible in the future)

Sent from Mailhttps: for Windows 10

From: Tim Robertsmailto:xxxxx
Sent: October 20, 2016 3:04 PM
To: Windows System Software Devs Interest Listmailto:xxxxx
Subject: Re: [ntdev] Pros n Cons of using Classes (CPP) at Kernel Level

xxxxx@hotmail.com wrote:
> Concerning Turing-completeness, your statement is just a classical example of red herring.
>
> The concept of Turing-completeness applies to computability of a function - if some function X can be computed in some Turing-complete language A (or C), it means that this function can be computed in any other Turing-complete language. However, this is not what we speak about here, right

It most certainly is. You accused me of thinking “there is … nothing
in C++ that cannot be done in C,” as if that were a bad thing. That is
exactly Turing completeness. Now, maybe that’s not what you meant to
accuse me of, but that is exactly what you said.

> C++ is positioned, described and advertised as an object-oriented language, while C is supposed to be procedural.

You’re making your own definitions so you can strike them down. Both of
these are procedural languages, and both of them are object-oriented.
C++ emphasizes objects more than C, and that’s why it is a better choice
for programs that focus on data, which is most programs.

> However, in actuality, all the advantages that OOP offers result from your way of thinking about the problem in question, rather than from a language that you use. If you have any doubts about it, take a brief look at Linux/xBSD/Solaris kernels - you will see that, in actuality, you can easily write OO programs in plain C, and do it just fine.

Of course it’s possible to write OO programs in plain C, but I dispute
your addition of the word “easily”. My work involves almost as much
Linux as it does Windows, so I have spent a great deal of time wading
through the Linux kernel. When one does so, what becomes obvious is
how painful it is to handle lists and queues and strings. Yes, they
absolutely have facilities for managing their data structures, and
drivers use them extensively, but they are wordy, finicky, and
error-prone. C++ simply lets me express those concepts in a way that is
less prone to mistakes.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.


NTDEV is sponsored by OSR

Visit the list online at: http:

MONTHLY seminars on crash dump analysis, WDF, Windows internals and software drivers!
Details at http:

To unsubscribe, visit the List Server section of OSR Online at http:</http:></http:></http:></mailto:xxxxx></mailto:xxxxx></https:>

???

Look what I had said earlier

Therefore, according to you , I must be accusing you of thinking exactly the same way that I do.
Does not really seem to make any sense, does it?

Concerning Turing completeness, again, I have to repeat myself - you are throwing a totally irrelevant argument into a discussion. Just to give you an idea, there are quite a few things that you can do in C but cannot do in a toy language like VB. Does it make VB “Turing-incomplete”???
As long as imperative language allows conditional branching and does not impose any theoretical limits on the number of variables that a function/procedure can access it automatically qualifies for
Turing-completeness. However, it does not make all imperative languages equal, does it?
If you think otherwise…well, then I would suggest making an experiment and writing you driver in VB or JavaScript. See if it works…

Both of these are procedural languages, and both of them are object-oriented.

C is object-oriented language??? What’s wrong with you today, Tim?

Anton Bassov

The above applies only to stack-based objects that appear as local variables - otherwise, the only thing that you may achieve is having to manually call operators new and delete instead of making acquire_resource_x() and release_resource_x() function calls.

However, if you decide to use it the former way…well, we may just have different tastes, but,IMHO, this is just a classical demonstration of why C++ offers nothing, apart from extra confusion.

Consider the situation when you have to maintain a reasonably complex resource-acquisition hierarchy and, at the same time, want to write high-performance code that does not keep the resources locked for ages and, instead, may, under some circumstances, temporarily release the resource that it owns with its subsequent re-acquisition. Doing something like that in C is pretty straightforward. However, I just don’t want to even think about the code complexity if you want to achieve the same results by means of objects entering and leaving the scope…

That’s a Nirvana fallacy. “This solution doesn’t solve all problems, so we should not use it,
even though it solves some problems.”

You are almost there - the “only” thing left is just to show some problem that this alleged “solution” _actually_solves, and you are done…

Anton Bassov

[quote] The above applies only to stack-based objects that appear as local
variables [/quote]

That’s what “modern C++” is supposed to be by default. If you’re doing a
bunch of new and delete in your C++ you’re not doing modern c++.

[quote] Consider the situation when you have to maintain a reasonably
complex [/quote]

This is a good example of why modern c++ is supposed to be safe by default
(guaranteed clean up in the destructor), but has the flexibility to do the
complex thing when you need it.

And here is a good example of where writing kernel mode C++ is different than writing user mode C++. In user mode you probably have a dynamically expanding stack of megabytes. In kernel mode, you have a stack of 16K or so. You ONLY want pretty small objects allocated in stack frames (like 64-bits of smart pointer) and anything bigger in pool memory.

Destructors in heap allocated objects get called too, if they are referenced by a smart pointer object that’s stack allocated.

Jan

From: on behalf of Jeremy Hurren
Reply-To: Windows List
Date: Thursday, October 20, 2016 at 9:51 PM
To: Windows List
Subject: Re: [ntdev] Pros n Cons of using Classes (CPP) at Kernel Level



That’s what “modern C++” is supposed to be by default. If you’re doing a bunch of new and delete in your C++ you’re not doing modern c++.



This is a good example of why modern c++ is supposed to be safe by default (guaranteed clean up in the destructor), but has the flexibility to do the complex thing when you need it.


— NTDEV is sponsored by OSR Visit the list online at: MONTHLY seminars on crash dump analysis, WDF, Windows internals and software drivers! Details at To unsubscribe, visit the List Server section of OSR Online at



> That’s what “modern C++” is supposed to be by default. If you’re doing a bunch
> of new and delete in your C++ you’re not doing modern c++.

Oh dear…

As I can see, there are different C++ flavours - “pre-historic C++”(a.k.a.C), “Ancient C++”,
“Medieval C++”, “Renaissance C++” and “Modern C++”.

We have had quite a few c vs C++ discussions here,which seems to be pretty boring. What I would propose here is to diversify our discussions. Would not it be great to have a thread titled like, for example, “Mixing Medieval C++ and Modern C++ in the same project”. Sounds exciting, don’t you think, guys…

> This is a good example of why modern c++ is supposed to be safe by default (guaranteed
>clean up in the destructor), but has the flexibility to do the complex thing when you need it.

It becomes more and more exciting - some posters see the above mentioned flexibility as C++ advantage while others refer to it as its biggest weakness …

Anton Bassov

> I can give plenty of examples. In fact years ago, it was examples such as

your that started the claims of better maintainability. As I stated when
people did real studies of maintainability, either by looking at a project
over the years, or by putting together code with such samples, then having
people debug it who had not built the example all the results came out
against C++.

This was a hot topic at the C++ standards committee, and while a number of
things were done to alleviate problems I never saw a study that said it had
been solved.

That sounds rather anecdotal. Can you cite any of those studies?

> Consider the situation when you have to maintain a reasonably complex resource-acquisition hierarchy and, at the same time, want to write high-performance code that does not keep the resources locked for ages and, instead, may, under some circumstances, temporarily release the resource that it owns with its subsequent re-acquisition. Doing something like that in C is pretty straightforward. However, I just don’t want to even think about the code complexity if you want to achieve the same results by means of objects entering and leaving the scope…
I’ve never encountered the need to do that, but you have a couple of
options.
You could have a TemporaryResourceRelease object that releases the
resource while it exists. The only issue is that if both that object and
the original resource object are going out of scope simultaneously (for
example, because of a return), the resource will be reacquired and then
immediately re-released. In the case of exceptions, this can be avoided.
Alternatively, you could use manual resource management only for those
resources that need it, and continue using RAII for the rest.

You are almost there - the “only” thing left is just to show some problem that this alleged “solution” _actually_solves, and you are done.
I think resource management is a problem in C. How often have you
written either of these code structures?

resource_a a = acquire_resource_a();
if (!a)
return;
resource_b b = acquire_resource_b();
if (!b){
release_resource_a(a);
return;
}
resource_c c = acquire_resource_c();
if (!c){
release_resource_b(b);
release_resource_a(a);
return;
}
//etc.

resource_a a = acquire_resource_a();
if (a){
resource_b b = acquire_resource_b();
if (b){
resource_c c = acquire_resource_c();
if (c){
//etc.
}else{
release_resource_b(b);
release_resource_a(a);
return;
}
}else{
release_resource_a(a);
return;
}
}

You mentioned another one: type safety. C will happily let you make
assignments that don’t make any sense.
You can argue that C++ introduces more or bigger problems than it
solves, compared to C. You can’t argue that it solves NO problems.

C++ is a nasty language in the sense that it is huge, and mastering it is not easy at least for me :(.

But some of the reasons I see ( may be I am not following ) - like allocating objects on stack ( this is purely because someone does not know how to code in C++. One can blow up stack in many ways in C too ). If a C++ programmer uses Obj++, I know for sure I found a friend who knows little less than me ( Yeah it is competitive world !).

The exception handling is what I think is the major problem. Yes, overloading operators and all those are problematics at time, but a brave programmer ( of course every one such animal should be brave, IMO !) should document those in there class design. I do by the way document, and I have used those.

But what Tim said about the simple way to use strings, and other stuff are invaluable.

A while ago, a wrote a thread pool in C++, it is way more simpler than writing in C where under *nix env., mutex + condition var is a must for such pattern. A 1500 line code becomes almost 100+ odd number of lines.

I think knowing one?s own limit is the main thing here. Overuse and unplanned approach will make any code rubbish …

-Pro

On Oct 21, 2016, at 8:53 AM, V?ctor M. Gonz?lez wrote:
>
>> Consider the situation when you have to maintain a reasonably complex resource-acquisition hierarchy and, at the same time, want to write high-performance code that does not keep the resources locked for ages and, instead, may, under some circumstances, temporarily release the resource that it owns with its subsequent re-acquisition. Doing something like that in C is pretty straightforward. However, I just don’t want to even think about the code complexity if you want to achieve the same results by means of objects entering and leaving the scope…
> I’ve never encountered the need to do that, but you have a couple of options.
> You could have a TemporaryResourceRelease object that releases the resource while it exists. The only issue is that if both that object and the original resource object are going out of scope simultaneously (for example, because of a return), the resource will be reacquired and then immediately re-released. In the case of exceptions, this can be avoided.
> Alternatively, you could use manual resource management only for those resources that need it, and continue using RAII for the rest.
>
>> You are almost there - the “only” thing left is just to show some problem that this alleged “solution” _actually_solves, and you are done.
> I think resource management is a problem in C. How often have you written either of these code structures?
>>
>> resource_a a = acquire_resource_a();
>> if (!a)
>> return;
>> resource_b b = acquire_resource_b();
>> if (!b){
>> release_resource_a(a);
>> return;
>> }
>> resource_c c = acquire_resource_c();
>> if (!c){
>> release_resource_b(b);
>> release_resource_a(a);
>> return;
>> }
>> //etc.
>
>> resource_a a = acquire_resource_a();
>> if (a){
>> resource_b b = acquire_resource_b();
>> if (b){
>> resource_c c = acquire_resource_c();
>> if (c){
>> //etc.
>> }else{
>> release_resource_b(b);
>> release_resource_a(a);
>> return;
>> }
>> }else{
>> release_resource_a(a);
>> return;
>> }
>> }
>
> You mentioned another one: type safety. C will happily let you make assignments that don’t make any sense.
> You can argue that C++ introduces more or bigger problems than it solves, compared to C. You can’t argue that it solves NO problems.
>
> —
> NTDEV is sponsored by OSR
>
> Visit the list online at: http:
>
> MONTHLY seminars on crash dump analysis, WDF, Windows internals and software drivers!
> Details at http:
>
> To unsubscribe, visit the List Server section of OSR Online at http:</http:></http:></http:>

>… like allocating objects on stack ( this is purely because someone does

not know how to code in C++.

How dare you - after all, this is “modern C++”…

The exception handling is what I think is the major problem.

For you (and not only you) it may be the one, but, as we can see, for some posters it is just a mechanism for handling complex code flow scenarios…

But what Tim said about the simple way to use strings, and other stuff are invaluable.

Yes, but who holds you back from writing a helper library in C that offers the same
functionality as, say, STL, especially if you have to deal with strings and structures like RB tree and AVL tree on a regular basis??? BTW, once we started speaking about the strings, your library may make string operations as safe as they are in managed languages - it is all your choice. In fact, you may go even further and give this a full-blown safety net that may approach the ones that managed languages offer…

Anton Bassov

xxxxx@hotmail.com wrote:

Yes, but who holds you back from writing a helper library in C that offers the same
functionality as, say, STL, especially if you have to deal with strings and structures like RB tree and AVL tree on a regular basis???

Absolutely true, but then I have to design it, write it, publicize it,
and evangelize it, and when I go to the next company I either have to do
it all over again, or learn their library that I don’t trust. With C++,
I don’t have to think about it. No matter where I go, I have
std::string and std::vector, and they work the same everywhere.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

Or you could be like me and issue an edict of the form:

Thou shalt use the library that thou hast been given!

And I tell them, if you don?t trust the code, read it ? its not long or complex ? and far less horrifying than reading the stl code IMHO

At least here in my shop we have a rule for systems programming: if you don?t understand it, don?t do it. The same does not apply for web development and GUI development of diverse forms, but for this sort of work ignorance is not bliss

Sent from Mailhttps: for Windows 10

From: Tim Robertsmailto:xxxxx
Sent: October 25, 2016 4:41 PM
To: Windows System Software Devs Interest Listmailto:xxxxx
Subject: Re: [ntdev] Pros n Cons of using Classes (CPP) at Kernel Level

xxxxx@hotmail.com wrote:
> Yes, but who holds you back from writing a helper library in C that offers the same
> functionality as, say, STL, especially if you have to deal with strings and structures like RB tree and AVL tree on a regular basis???

Absolutely true, but then I have to design it, write it, publicize it,
and evangelize it, and when I go to the next company I either have to do
it all over again, or learn their library that I don’t trust. With C++,
I don’t have to think about it. No matter where I go, I have
std::string and std::vector, and they work the same everywhere.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.


NTDEV is sponsored by OSR

Visit the list online at: http:

MONTHLY seminars on crash dump analysis, WDF, Windows internals and software drivers!
Details at http:

To unsubscribe, visit the List Server section of OSR Online at http:</http:></http:></http:></mailto:xxxxx></mailto:xxxxx></https:>

As a follow-up to my previous post about C# and drivers I would like to provide the following link

https://tommd.wordpress.com/2009/09/13/kernel-modules-in-haskell/

In other words, the whole thing seems to be,indeed, far from infeasible - if someone managed to do it in HASKELL (!!!) C# definitely can do. Certainly,performance may potentially be an issue here,but this is already a different story…

Anton Bassov

I don’t know what the mystery is, Mr Bassov. You know there are c# drivers in Singularity… we’ve discussed them before here.

Peter
OSR
@OSRDrivers

This has been a fascinating thread to read. From experience, I have found
C++ to be more beneficial in large scale projects that are well defined.
These tend to be user-mode projects. I have yet to work on a Windows driver
(and I have worked on quite a few) where I felt it was required to add the
additional layers offered by C++. The only C++ feature I might find useful
would be data structure inheritance. I think I compiled one driver using
.cpp extension at one time in the past.

When writing drivers, we really don’t want things to be hidden, or obscured
by the language we choose. It is hard enough producing a reliable driver. I
can imagine a situation where someone working on a large piece of code such
as a filesystem might be tempted to use C++, and depending on the
complexity of the filesystem, maybe C++ may be useful. But I don’t really
think it offers much. I am still not much of a fan of the kernel mode
driver framework either.

If you start to find benefit to using C++ in your driver, I would
re-evaluate the design; you’re probably doing too much in the kernel.

On Sun, Oct 30, 2016 at 2:44 PM wrote:

> I don’t know what the mystery is, Mr Bassov. You know there are c# drivers
> in Singularity… we’ve discussed them before here.
>
> Peter
> OSR
> @OSRDrivers
>
>
> —
> NTDEV is sponsored by OSR
>
> Visit the list online at: <
> http://www.osronline.com/showlists.cfm?list=ntdev&gt;
>
> MONTHLY seminars on crash dump analysis, WDF, Windows internals and
> software drivers!
> Details at http:
>
> To unsubscribe, visit the List Server section of OSR Online at <
> http://www.osronline.com/page.cfm?name=ListServer&gt;
></http:>

> I don’t know what the mystery is, Mr Bassov. You know there are c# drivers in Singularity…

Actually, I think there are 2 mysteries here

1.Small mystery. They are attempting to integrate their project into the existing OS kernel
that is meant to be developed only in C. The concept of using managed languages for the system-level development is not new - just look at Singularity or JNode.However, an attempt to
integrate such a project into the existing mainstream OS kernel seems (at least to me) to be much more challenging

2.Big mystery. In addition to above mentioned issues they have chosen a purely functional language that seems (at least to me) to be the least suitable language for the system-level development that one may possibly imagine

Anton Bassov