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

Let?s say that we are loudly agreeing rather than disagreeing. My point was that both C and C++ can be equally fit, by virtue of being supported by MSFT. Even though you have already heard my option on the use of the latter, you understand that equally fit may still mean horribly inefficient and effort prone but there is nothing better. As Anton has suggested, would you write a driver is lisp? That would be much less fit for the purpose.

I am tempted to remind everyone what the purpose of ring 2 was, but as you say, very few are interested in this today

Sent from Mailhttps: for Windows 10

From: xxxxx@osr.commailto:xxxxx
Sent: October 17, 2016 6:33 PM
To: Windows System Software Devs Interest Listmailto:xxxxx
Subject: RE:[ntdev] Pros n Cons of using Classes (CPP) at Kernel Level



I agreed with everything you wrote RIGHT up to this point.

TL;DR –> If there were more new, cutting-edge, OS work being done, it’d move the state of the art on to using better languages… where it’s not possible to do stupid stuff like use after free or overrun buffers. But that work’s not being done, so we’re stuck in the 20th century using a hideously outdated language like C/C++ for KM work. Oh well, whatever, never mind.

Long version:

I’ve argued this before. I would say that C and C++ are particularly BADLY fit for KM development in the 21st century. Inherent support for buffer overruns, memory leaks, use after free, bad pointer references… all make for a language that is PARTICULARLY poorly suited to KM use in the modern era. Why on EARTH is it possible to index past the end of an allocated array without being told? This is just one example of a language construct that is NOT reasonable in the 21st century.

I used to write drivers in assembler language. I was very good at it. But it was time-consuming and unnecessarily difficult once compilers became clever enough to efficiently translate their higher-level constructs into machine language. Because there was lots of OS work going on, it became possible for different projects to “try out” different languages and move the majority of work to higher level languages.

We’re at the point now where it’s no longer necessary to write KM code in ancient, bug prone, languages… where the most rudimentary errors can linger undetected and cause problems. But there’s not enough new OS development work happening to facilitate the movement of OS work to new languages. You’ve got a huge body of existing work, enormous vested interests with giant installed user bases, and no impetus to change. So… we’re stuck with C. Or C++.

C/C++ is not better, it’s ancient. But this is a sort of ancient field.

Peter
OSR
@OSRDrivers


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:>

Marion Bond wrote:

Let’s say that we are loudly agreeing rather than disagreeing. My
point was that both C and C++ can be equally fit, by virtue of being
supported by MSFT.

Well, that’s a very different question. The fact that they are
supported doesn’t really impact their fitness for use in kernel programming.

Even though you have already heard my option on the use of the latter,
you understand that equally fit may still mean horribly inefficient
and effort prone but there is nothing better. As Anton has suggested,
would you write a driver is lisp? That would be much less fit for the
purpose.

I also have to disagree. I think you are confusing certain specific
implementations of a language with the potentials of the language
itself. It’s essentially a Turing machine question. Virtually all of
the languages you mention are equivalent, it’s just that the concepts
are spelled differently. A kernel based on a function language would
have a number of advantages over those based on procedural languages,
including much more rigorous support for multiprocessing. There have
certainly been operating systems written in Lisp, and I assume there
must be an operating system in Redmond written in F#. It would be ideal
for that.

I am tempted to remind everyone what the purpose of ring 2 was, but as
you say, very few are interested in this today

There wasn’t “one purpose” for ring 2. The ring concept came from
Multics, where there were 16 different rings, intended to isolate
various operating system functions from one another. I spent 10 years
with Control Data; their Cyber 180 mainframes borrowed the 16 ring
concept, and actually used 9 of them. Applications ran in ring 13. You
had to transition to ring 12 call the user-level APIs in ring 9, and
they in turn had to transition to ring 8 in order to call kernel APIs in
ring 2. It was far more transparent than it sounds.


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



Take the CLR away from C#. It would make me sad.





If there were more new, cutting-edge, OS work being done, it’d move the state of the art on to using better languages… where it’s not possible to do stupid stuff like use after free or overrun buffers. But that work’s not being done, so we’re stuck in the 20th century using a hideously outdated language like C/C++ for KM work. Oh well, whatever, never mind.



Well, I am afraid you have to get your priorities right. You can either have a cake in the fridge or eat it, but you cannot do both with the same cake (you can make a simple experiment if you don’t believe me - just take a cake out of the fridge, eat it, and then check if it is still in the fridge).

Similarly, you can either use the existing CRL or write KM drivers in C#, but you cannot do both.
If you want to use C# for KM development the very,very first thing that you have to do
is to replace the existing CLR with its KM equivalent that is based upon the calls to the kernel functions, rather than userland ones that CRL relies upon. More on it below.



The fallacy of the above statement is the assumption that some " new OS development work" is needed in order “to facilitate the movement of OS work to new languages”. I can assure you that
designing a new OS from the scratch for the sole purpose of using new languages (in fact, for ANY
purpose) is a way to the middle of nowhere - an OS like that is just doomed to maintain its status of a research project for its entire lifetime, without any chance of general acceptance (just look at Singularity if you don’t agree with me).

Why? Simply because no one needs it - there are few major OSes with HUGE ecosystems in terms of both applications and drivers, and neither drivers writers nor app developers nor end users need anything new. Therefore, the only thing you can get from such a project is sort of intellectual satisfaction - despite the obvious intellectual stimulation that such a project offers, its practical usefulness seems to be pretty close to zero.

Sounds hopeless? Not really - I think that you may have a success if you approach the whole thing from another end and start integrating your managed language KM development framework into the existing OS kernels. What you need here is:

1. An implementation of KM runtime library that your managed language relies upon

2. A relatively simple compiler for your language. The purpose of this compiler is to transform
your managed language into something that can be subsequently fed to WDK/GCC/LLVM C compiler/linker toolchain that _actually_compiles your resulting C sources and links them against your runtime library (which is also written in C), effectively producing a driver binary for the target OS kernel. In fact, you can think of it just as of some extended C pre-processor for the existing C compiler of your choice (which it, indeed, is)

This approach seems to be already, indeed, promising - once you start developing the new features
without disrupting anything that the entire developer and user communities know and love you already have a chance of getting gradually accepted. At some point a general driver developer’s community will realize that, indeed, " it’s no longer necessary to write KM code in ancient, bug prone, languages… where the most rudimentary errors can linger undetected and cause problems."
However, it has to be a gradual process…

Anton Bassov

Regarding c++, there are 3 types of people here:

  1. The type that use c++ to their detriment
  2. The type that use c++ to their benefit
  3. The type that do not use c++ because they haven’t figured out any way to benefit from it

Type 3 refuses to believe type 2 exists. The reason should be obvious.

Microsoft already has a pure native code C# compiler. My understanding is it gobbles up your C# .Net program, and finds all the classes required from all the libraries, and generates a single native binary.

See https://msdn.microsoft.com/en-us/library/dn584397(v=vs.110).aspx

Jan

On 10/17/16, 9:32 PM, “xxxxx@lists.osr.com on behalf of xxxxx@hotmail.com” wrote:

Take the CLR away from C#. It would make me sad.

NOW all we need to do is get them to let us use it to write drivers.

How hard could THAT be? :wink:

Peter
OSR
@OSRDrivers

(For removal of doubt: That last sentence was sarcasm. It was tried, it was abandoned, and to the best of my knowledge that’s not an idea that’s coming back soon.)

> NOW all we need to do is get them to let us use it to write drivers. How hard could THAT be? :wink:

What about DIY approach? I know it is quite uncommon idea in the world that you happen
to be in (whatever you do has to be approved by MSFT - otherwise the usual suspects start shouting in capitals all over the place), but still…

Anton Bassov

> A kernel based on a function language would have a number of advantages over those

based on procedural languages,

Could you please explain the above statement in more detail.

Up to this point I don’t see ANY use of a functional language for this purpose. Why? Simply because the very idea of the OS kernel is to schedule threads, handle synchronisation, memory mappings,etc. All above mentioned things are all about managing and manipulating the state of the objects.

However, you propose to handle them in some language that that does not allow the side effects and requires various cumbersome workarounds (co-routines, monads,etc)that are meant to simulate the side effects and program state.

The only thing that I have heard of in this respect is a formal verification that C implementation of a microkernel fully conforms to its purely functional prototype in Haskel . However, its actual implementation is still in C.

http://web1.cs.columbia.edu/~junfeng/09fa-e6998/papers/sel4.pdf

Anton Bassov

xxxxx@hotmail.com wrote:

> A kernel based on a function language would have a number of advantages over those
> based on procedural languages,
Could you please explain the above statement in more detail.

Up to this point I don’t see ANY use of a functional language for this purpose. Why? Simply because the very idea of the OS kernel is to schedule threads, handle synchronisation, memory mappings,etc. All above mentioned things are all about managing and manipulating the state of the objects.

Erlang was specifically designed for the operating systems in telephone
switches. It has achieved wide deployment in mobile network switching
systems today.

F# does have “impure” extensions to allow side effects for interfacing
to the real world. It’s the concepts that functional languages enforce
that lead to things like easier parallelization and fewer
synchronization issues. Even though I don’t program in F#, learning it
has helped me do things more intelligently in C++.


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

> Erlang was specifically designed for the operating systems in telephone switches.

Erlang is just a high-level language that requires a RT library that does more basic tasks like scheduling,garbage collection and error checking. This definition alone seems to be sufficient to realize that its purpose is designing high-level userland message-based apps, and,AFAIK, this is how it is used in telephony. It has absolutely nothing to do with low-system-level development like thread scheduling and address space/memory management…

You can check https://en.wikipedia.org/wiki/Erlang_(programming_language) - please pay a special attention to “Software projects written in Erlang” part

Therefore, the only possibility that I can see for such a language in the KM is more or less the one
that I have described in my reply to Peter, i.e. a RTL that relies upon the kernel exports, plus
a tool that transforms this language to C

Even though I don’t program in F#, learning it has helped me do things more intelligently in C++.

Well, “intelligence” may be a relative concept. …

For example, some people may read the above statement as “It showed me possibilities of using even more esoteric C++ features in even more convoluted ways” .The author of a book that I had earlier mentioned on this thread very obviously falls into this class.

Some other people (including myself) may read it as “It made me realise that there is ABSOLUTELY nothing in C++ that cannot be done in C, so that now I use only those C++ constructs that can be compiled in a file with .c extension”…

Anton Bassov

> Some other people (including myself) may read it as “It made me realise that there is ABSOLUTELY nothing in C++ that cannot be done in C, so that now I use only those C++ constructs that can be compiled in a file with .c extension”…

I think that’s the wrong way of looking at things. There’s also nothing
you can do in C that you can’t do in Assembly, yet I’m sure the majority
of your code is not Assembly.
C++ does have facilities that when used appropriately can help to
minimize programmer error. The most important of which is, in my
opinion, RAII.

Language defines Machine Architecture and our perception of interface to the machine. Stored program and our perception of register based machines drove us thru assembler and then A, B, C (whatever) languages.
In general, there have been and still are lot of work around this area, people come up with different languages. So running a machine to give the perception of many machines ( or very large memory etc) are not necessarily tied to any languages. People works on AI machines with their choices of languages too ?

-Pro

On Oct 20, 2016, at 8:30 AM, V?ctor M. Gonz?lez wrote:
>
>> Some other people (including myself) may read it as “It made me realise that there is ABSOLUTELY nothing in C++ that cannot be done in C, so that now I use only those C++ constructs that can be compiled in a file with .c extension”…
>
> I think that’s the wrong way of looking at things. There’s also nothing you can do in C that you can’t do in Assembly, yet I’m sure the majority of your code is not Assembly.
> C++ does have facilities that when used appropriately can help to minimize programmer error. The most important of which is, in my opinion, RAII.
>
> —
> 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:>

Although the above argument seems perfectly reasonable at the first glance,after thinking a bit one realises that,in actuality,it is specious.

Unless you are trying to win some C obfuscation contest it is virtually impossible for you to write C code that,compared to assembly, is more hard to understand and maintain. You cannot say the same thing about the relationship between C and C++, can you…

[quote]

C++ does have facilities that when used appropriately can help to minimize programmer error.

/quote>

To be honest, I cannot think of any, apart from type safety - you are still able to overrun buffers, corrupt stacks, get random results due to a function returning the address of its local variable and do all other stupid things that C compiler allows to go undetected. Therefore, in this respect C and C++ are in the same position.

However, it also offers PLENTY of features that allow programmers to maximise their errors, especially if they have to maintain the code written by someone who thinks that relying upon some esoteric feature of a language is a sign of “expertise”, rather than that of a low professionalism.

Anton Bassov

xxxxx@hotmail.com wrote:

Some other people (including myself) may read it as “It made me realise that there is ABSOLUTELY nothing in C++ that cannot be done in C, so that now I use only those C++ constructs that can be compiled in a file with .c extension”…

You have a bad habit of assuming your conclusion, then using that
assumption to prove what you’ve already decided. Of course there is
nothing in C++ that cannot be done in C. The same applies to C#, and
for that matter, F#, Lisp, and Forth. They are all Turing-complete.

The point is that I (personally) can express the same concepts in C++
more quickly, more reliably, and more readably in C++ than I can in C.
It’s absolutely true that a C expert is going to remember to clean up
his local variables, and look after his pointers, and encapsulate his
state. But when someone else comes along to update the code who isn’t
as good, bad things happen. With C++, I don’t have to do all those
things by hand. The next guy inherits the benefits of the language, and
doesn’t have to learn the practices of a great programmer.


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

Probably echoing what others have said, but… doesn’t a lot of this
argument sound like “I’m not very good at writing or understanding C++, but
I am in C, so C++ must suck?” (Or vice versa.) While related, they are
definitely different languages. You can be a good programmer in either or
both. But if you’re not good at one, programming in it will be hard.

> Unless you are trying to win some C obfuscation contest it is virtually impossible for you to write C code that,compared to assembly, is more hard to understand and maintain. You cannot say the same thing about the relationship between C and C++, can you.

“Trying to win an obfuscation contest” is a question of intent, not a
question of result. Nobody who’s writing software professionally sets
out to write unmaintainable code (well, perhaps some unscrupulous people
do, but that’s beside the point), but it is something that can happen
unintentionally. An incompetent programmer can unintentionally write a
labyrinth of a codebase in any language.
While C++ can be more difficult to understand, because it requires more
context to understand a given line, well-designed C++ code can be more
maintainable than well-designed C code because the compiler enforces
more rules, so it can be used to enforce constraints. For example, while
a new arrival to a C project might not not that every
acquire_resource_x() must be paired with release_resource_x(), the C++
compiler can be made to ensure that every call to ResourceX::ResourceX()
that returns (without exceptions) is paired with a
ResourceX::~ResourceX() call.

To be honest, I cannot think of any, apart from type safety - you are still able to overrun buffers, corrupt stacks, get random results due to a function returning the address of its local variable and do all other stupid things that C compiler allows to go undetected.
That’s a Nirvana fallacy. “This solution doesn’t solve all problems, so
we should not use it, even though it solves some problems.”

"While C++ can be more difficult to understand, because it requires more
context to understand a given line, well-designed C++ code can be more
maintainable than well-designed C code because the compiler enforces more
rules, so it can be used to enforce constraints. "

Can you give any reference for this? I have seen this claim for most of the
30+ years of having been involved with C++, and every time someone actually
did a study (though I will admit it has been years since I have any real
studies), they proved the opposite.

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

> 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:>