On the Wikipedia page for Windows, it states the Windows is written in Assembly for the bootloader and task switcher, and C and C++ for kernel routines.

IIRC, you can call C++ functions from an extern "C"'d block. I can get using C for the kernel functions so pure C apps can use them (like printf and such), but if they can just be wrapped in an extern "C " block, then why code in C?

13 Answers
13

It's mostly for historical reasons. Some parts of the windows kernel were originally written in C, because 1983, almost three decades ago, when Windows 1.0 was unleashed, C++ was barely released.
Now these C-libraries will stay there "forever", because Microsoft made backward-compatibility a selling point and rewriting a bug-compatible version of the C-parts in C++ requires an awful lot of effort for no effective benefit.

+1, I guess that is the most realistic answer (besides the fact that there might be some Windows kernel devs who just don't like C++ or don't trust C++ compilers for that low-level stuff). Look, for example, here stackoverflow.com/questions/520068/…, why the Linux kernel is written in C.
–
Doc BrownDec 10 '12 at 18:07

@back2dos - While their C code won't be thrown away that doesn't mean it will be used or not updated. I guarantee you there is a least one method that does something that was originally written and contained within a C library that has been ported a C++ library in Windows 8
–
RamhoundDec 10 '12 at 18:09

6

I have a hard time believing that there is any Windows 1.0 code in any recent release of Windows. Windows ME was the last Windows release that wasn't based on the Windows NT code base. And even that has been largely replaced by the new RT kernel (which, as I understand it, doesn't promise very much in the way of backwards compatability).
–
TMNDec 10 '12 at 18:23

@TMN: the argument is most probably correct either - I am pretty sure on the road from Win 1.0 to now there were a lot of libraries written in C which are still part of the current Win8 code base, and no one at MS sees any benefit to rewrite them in C++.
–
Doc BrownDec 10 '12 at 21:37

There is hardly any code which talks to the Windows kernel anyway. Basically, only drivers do. Applications usually talk to the Win32 API, or possibly the POSIX API.
–
MSaltersDec 11 '12 at 12:33

As most people have pointed out, reasons are by far historical, but there is something else no one is mentioning and I believe it is the reason people still write C code for low-level.

C is a small language in the sense that the spec is (relatively) short. C++ is huge and that's an understatement. This may not matter that much to the programmer (although I think it does), but it is extremely important if you want to do formal verification. Furthermore there are established tools for C code analysis, that could help prevent bugs, etc.

And this is very important in embedded software, where the cost of a bug that is deployed is extremely high, relative to the rest of the industry (compare Web, where you can apply a patch immediately to all users). Not to mention mission-critical software and medical stuff.

There have been attempts to displace C from its dominant place in low-level programming with languages that are even better at this, like BitC, but they haven't been successful so far.

+1 For mentioning mission critical software in pure C (e.g. aeronautical software). However, in medical software C++ is also used (extensive testing is used instead of a formal verification, which would be extremely hard in C++).
–
GiorgioDec 11 '12 at 6:18

1

Also, C has a rather successful safe subset MISRA-C. There are equivalents for C++, but they aren't industry de facto standard (yet). The trend in safety-critical programming is that libraries and compilers will also be forced to use a safe subset like MISRA. To re-write a MISRA-C++ compatible version of the whole C++ standard library will most likely be a nightmare.
–
user29079Dec 11 '12 at 15:55

2

@Lundin MISRA guidelines are not a safe subset - you still have raw pointers and most other features which make C unsafe - they mainly focus on not using or documenting implementation specific behaviour.
–
Pete KirkhamFeb 6 '13 at 8:59

@PeteKirkham MISRA-C will catch all the most classic pointer bugs and enforce static analysis. Industry safety standards (IEC 61508 et al) apparently approve MISRA-C as a safe subset of C. There aren't many other useful alternatives for mission-critical software, unless you pick SPARK Ada, a language that few know, with limited tool support.
–
user29079Feb 6 '13 at 13:02

The translation of C++ into lower-level constructs is less transparent than in C. (See references and vtables, for two quick examples)

C usually has a stable ABI. C++ usually does not. This means that at the bare minimum, the system call interface should be C style. In addition, if you want any sort of dynamic modules, having a consistent ABI helps greatly.

@Thomas Eding: The C++ runtime consists of the C runtime, plus C++ features such as a exceptions, RTTI, and another memory allocator. YMMV as to whether that counts as much larger. (And then there's the standard library...)
–
wnoiseDec 11 '12 at 23:26

Ah, I forgot about exceptions and new/delete pools. RTTI I never use though :D
–
Thomas EdingDec 11 '12 at 23:32

The reasons aren't technical. A little bit of assembly is unavoidable, but they aren't forced to use the occasional C, they want to. My company uses its own proprietary kernel, written almost entirely in C++, but we don't need to support a C interface to the kernel like most everyone else, because our embedded kernel is monolithically compiled with our C++ applications. When you have a C interface, it's often easier to write the interface code in C, even though it's possible to use extern "C" to write it in C++.

Even we have a smattering of C files, mostly due to third-party code. Third-party low-level code is almost always provided in C, because it's much easier to incorporate C code into a C++ app than the other way around.

Kernel developers are often the kind of people, who feel happier, when it is immediately evident from the source, what the code actually does.

C++ has many more features, which hide what the code does more than plain C code hides it: overloads, virtual methods, templates, references, throws... C++ also has vastly more syntax you have to master in order to even understand the C++ code using it.

I think power of C++ is very powerful tools to create libraries and frameworks, which then make application development a snap. Very often C++ application developer would be totally lost in the template-filled innards of a library, even when he is very competent at creating applications using that library. And writing a C++ library right is a very challenging programming task, and only done in order to provide a great framework for the benefit of application developer. C++ libraries are not internally simple, they are (or can be...) just powerful yet simple from application programmers point of view.

But kernel API can not be a C++ API, it must be a language-agnostic API, so most of the nice things in C++ would not be directly usable at that interface. Furthermore, kernel is not really divided into "library" and "application" parts developed independently, with more effort logically going to one library, to make creation of a mass of applications easy.

Also, security and stability is more critical inside a kernel, and virtual methods are much more dynamic and therefore much harder to isolate and verify, than plain callbacks or other C-like mechanisms.

In short, while you could of course write any C program including a kernel as C++, most of the power of C++ is not well used in kernel. And many would argue, that programming tools should prevent you from doing things you should not do. C++ would not.

C is a very low-level language, by its design. It's one step away from assembler; knowing the chipset you're targeting, you could, with a little knowledge, manually "compile" C into ASM. This kind of "close-to-the-metal" language is key for high levels of optimization (for performance, memory-efficiency, etc). However, because it's this close to the metal, you don't get much for free with this language; it is a procedural, non-object-oriented language, and thus to work with such constructs involves a lot of boilerplate code to create and consume multi-value constructs in memory.

C++ is "C one better", adding a number of ease-of-use features such as dynamic memory allocation, built-in structure marshalling, a large library of predefined code, etc, at the expense of some efficiency losses (still much better than managed-runtime environments). For the average coder, the advantages far outweigh the disadvantages in areas of the codebase that don't need anal-retentive control of memory allocation etc.

The combination of the two is a pretty traditional one; you use C to write the most performance-critical, memory-efficient areas of the codebase, which you can then work with in a more abstracted fashion via method calls from C++ code, which can be more elegantly organized and designed than the uber-performant, uber-oogly optimized C code.

Regarding efficiency, I'll repeat myself: (1) The C++ folks will tell you that's bullshit. (2) I'm saying I see no reason this ought to be the case, and would like concrete examples. Not examples of how it's easy to write less efficient code, but examples of how being as efficient as C requires undue ugliness.
–
delnanDec 10 '12 at 18:18

3

Define "ugly"; I code in C# for a living, and whenever I see C++ code examples in StackOverflow I cringe at how much cruft is considered normal in the day-in-day-out usage of the language. When I coded in C++ way back when, I often saw C code and cringed; hand-packing structure types, execution pointer calculations for manual jumps, embedded ASM... yuck. Some people bemoan the loss of low-level knowledge among Java/.NET programmers; I consider it a huge boon to productivity.
–
KeithSDec 10 '12 at 18:27

1

You didn't answer my question ;) By "ugly" I mean "ugly by C++ gurus' standards". In other words, examples where one cannot use "modern C++" and be as efficient as C.
–
delnanDec 10 '12 at 18:30

2

That may be true (I honestly don't know). For kernel development (and a few other fields), we're not talking about average programmers though.
–
delnanDec 10 '12 at 20:42

3

People forget that C -> C++ is a continuum. Too often, these arguments are comparing good, modern C++ with C. You can take a C program and get it compiling with a C++ compiler in a relatively short time and it will run exactly as fast. If a modern C++ feature is "too slow", don't use it. That can even include things like iostream. "Too slow" is never a good excuse to use C over C++.
–
Steven BurnapDec 13 '12 at 18:22

I think you have it backwards -- the extern "C" block ensures that the C calling conventions are used for all functions within the block. So you can call pure C functions from C++, not C++ functions from C. Regardless, I imagine that the reason people use both C and C++ is because a lot of low-level libraries are written using C, and it's easier to use something that already exists (and is presumably debugged and optimized) than writing your own. OTOH, C++ offers a lot of nice high-level features that people would rather work with, so they use that for the rest.

It could be that with C you spend most of your time thinking about the problem at hand and how to code the solution. In C++ you end up thinking about C++ and its myriad of features, functions and obscure syntax.

Also in many C++ shops your code get monitored by the "fashion police" who are enthralled by the latest set of design patterns, or, the latest unintelligible pronouncements of the great god Stroustrup. Pretty code becomes more valued than working code, finding a use for the latest set of Boost templates is admired more than finding a working solution for the business.

My experience is that for all the clever features and OO purity of C++, coding in plain C gets the job done quicker and more effectively.

(1) The C++ folks would beg to differ. And objectively I see no reason this should be the case. (2) C++ can call into C code just fine (that's the whole point of backwards compatibility and extern "C").
–
delnanDec 10 '12 at 17:54

1

If MS uses some parts of the Linux kernel, and the Linux kernel is GPL, wouldn't that mean that Windows would also have to be GPL?
–
TomJDec 10 '12 at 17:55

1

@TomJ actually that's why they were forced to donated a couple thousands of lines to Linux as well. + Why do you think they support Linux development?
–
PiusDec 10 '12 at 17:57

2

@Pius His point is (and he's right AFAIK), if there was GPL's code linked into the Windows kernel, the whole kernel would have to be GPL'd (provided there isn't a separate agreement with the copyright holders).
–
delnanDec 10 '12 at 17:58

@delnan, not sure about the details. I'm not a lawyer so I cannot comment on that. But there was a small scandal a couple years ago about this. Not sure but I think I might have been the networking module all the crazy stuff was about.
–
PiusDec 10 '12 at 18:00

-1 for [stuff] that C++ expects. Why does C++ use more heap than C? Why does C++ require more dlls than C? Simply NOT TRUE
–
Thomas EdingDec 10 '12 at 17:56

1

Correction: You lose the libraries that are written in C++. So its back to square 1 if you are using C++ or C. Why limit yourself to C functionality if you can use templates, classes, destructors, const, and all sorts of other goodness.
–
Thomas EdingDec 10 '12 at 17:59