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?

  • 10
    Have you seen the various "Why use C when there's C++?" questions here? This isn't necessarily a duplicate of any of them, but they are related. – user7043 Dec 10 '12 at 17:56
  • 1
    "you can call C++ functions from an extern "C"'d block as C++" Do you mean you can call C functions...? – Code-Guru Dec 11 '12 at 4:36
  • @Code-Guru no, because the only difference between exported C and C++ functions is the name decoration and in C++, the addition of the this variable – Cole Johnson Dec 11 '12 at 4:56
  • 2
    Throw an exception in an ISR and see what happens – James Feb 6 '13 at 2:50
  • Yet another C vs. C++ question. – Machado Sep 30 '16 at 12:54

13 Answers 13


It's mostly for historical reasons. Some parts of the windows kernel were originally written in C, because 1983, over 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.

|improve this answer|||||
  • +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 Brown Dec 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 – Ramhound Dec 10 '12 at 18:09
  • 8
    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). – TMN Dec 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 Brown Dec 10 '12 at 21:37
  • 1
    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. – MSalters Dec 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.

|improve this answer|||||
  • 4
    +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++). – Giorgio Dec 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. – user29079 Dec 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 Kirkham Feb 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. – user29079 Feb 6 '13 at 13:02
  • 2
    This should have been selected as the best answer as it's correct. Others who suggest C is only used for historical reasons is hysterical in itself. – Rob Sep 30 '16 at 12:28
  1. The C runtime is much smaller.
  2. The translation of C++ into lower-level constructs is less transparent than in C. (See references and vtables, for two quick examples)
  3. 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.
|improve this answer|||||
  • +1 for (2) and (3). I'm not convinced with (1). – Thomas Eding Dec 11 '12 at 8:47
  • 7
    @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...) – wnoise Dec 11 '12 at 23:26
  • Ah, I forgot about exceptions and new/delete pools. RTTI I never use though :D – Thomas Eding Dec 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.

|improve this answer|||||

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.

|improve this answer|||||
  • +1. As a kernel developer my "rule of thumb" is that if you can't estimate "cache lines touched" easily then the language you're using is doing more harm than good. – Brendan Sep 30 '16 at 21:58
  • Clarification: For kernels you have to assume that CPU spends most its time in user-space and kernel code is used sporadically (e.g. when user-space calls kernel API or an interrupt occurs); which means that you have to assume "cold cache". For modern CPUs (where RAM is slow relative to CPU speed) cache and TLB misses are expensive, so (combined with the "cold cache" expectation) the "cache lines touched" metric becomes an extremely important indicator for performance and/or scalability. – Brendan Sep 30 '16 at 22:07

Bjarne Stroustrup, in an interview in July 1999:

None of these languages was radically different or dramatically better than other contemporary languages. They were, however, good enough and the beneficiaries of luck and social factors

|improve this answer|||||
  • 2
    Welcome David. When citing or quoting, it is a good idea to provide a reference (added!) – Andrew Dec 11 '12 at 6:10

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.

|improve this answer|||||
  • 2
    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. – user7043 Dec 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. – KeithS Dec 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. – user7043 Dec 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. – user7043 Dec 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++. – Gort the Robot Dec 13 '12 at 18:22

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.

|improve this answer|||||

It's possible that the C parts are not nicely portable to the C++ compiler that is used for the C++ parts. Maybe the C code is chummy with the C compiler in ways that break with the C++ compiler.

If you have a quality C++ compiler, there is almost no reason to mix C and C++ in a project. Almost.

The one reason would be that your project shares C code with other projects, the code does not compile as C++, and you don't want to maintain a C++ fork of that that code.

|improve this answer|||||

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.

|improve this answer|||||

There are various level of embedded platforms using C as programming language ( of course it is your freedom to use assembly language at any time )

For 'Level' I am talking about the Internal SRAM and ROM resource level for a system.

These platforms sometimes are resource constrained ( e.g. some 8051 platforms only have 128 bytes of User SRAM ).

It is meaningless to support dynamic memory allocation with such a small amount for RAM. (new/delete) or even malloc in C.

One of the main improvement from C to C++ is Object-oriented paradigm. C++ is suitable in software with larger memory footprint

but not in embedded firmware that have its size limitation up to 32KB. (e.g. in a 16-bit MCU plaform )

There is no need to have a C++ compiler which is generally more complicated than C compiler. ( at least SDK providers won't bother to do this ).

In fact I can hardly find a C++ compiler over an 32-bit ARM7 platform.

It just doesn't worth the complexity

In Some 8051(8 bit) : 1MB ROM, 128B RAM

TI MSP430(16 Bit) : 32KB ROM , 4KB RAM

ST Microelectronics ARM 32-bit Cortex™-M3 CPU Core ( STM32F103T4 ) : 16 or 32 Kbytes of Flash memory 6 or 10 Kbytes of SRAM

|improve this answer|||||
  • 2
    This doesn't anything new to the other answers already posted here. – Martijn Pieters Jul 9 '14 at 10:48
  • A 32-bit C++ compiler for ARM? If you wanted, you could compile LLVM from the source yourself after a few modifications to get a C++ compiler for iOS. – Cole Johnson Jul 10 '14 at 19:20

I see a couple of possible reasons:

  • C is a little bit more efficient if compared to the C++ equivalent.
  • Some libraries they use are written in C.
  • They use some parts of Linux kernel, which is written in C.

Edited: As it turns out, third argument is not true (see comments).

|improve this answer|||||
  • 5
    (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"). – user7043 Dec 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? – TomJ Dec 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? – Pijusn Dec 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). – user7043 Dec 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. – Pijusn Dec 10 '12 at 18:00

Because C is arguably a better language than C++. And because some of the code was written before C++ became popular and people haven't had a reason to replace it.

And because C++ has lots of features that can break your code if you're not careful when using it in a kernel.

|improve this answer|||||
  • C++ expects dynamic libraries? And what's dynamic memory? – user7043 Dec 10 '12 at 17:55
  • 4
    -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 Eding Dec 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 Eding Dec 10 '12 at 17:59
  • 6
    What? Templates, exceptions, objects (including constructors, destructors, overloaded operators, now move construction, and - practically? - everything else), etc. work just fine regardless where the memory's from (stack, static memory, your custom pool, or whatever). The standard containers use heap allocation by default, but their allocators can be customized and kernel guys write their own collections and memory management anyway. -1 – user7043 Dec 10 '12 at 18:00
  • 2
    FYI: I removed my downvote because I don't think your answer is actively harmful by now, but I don't consider it particular useful or insightful either. – user7043 Dec 10 '12 at 18:19

Not the answer you're looking for? Browse other questions tagged or ask your own question.