I know that C is the standard programming language for operating system development, but out of curiosity I was wondering what preceded it. What was the main programming language used for operating system development before C?
There were a lot of systems before C was used for Unix (1969...). Here's a sparse timeline. Click on each system for details. Most early systems would be implemented in assembler. A notable exception (not listed in the timeline) was the ahead-of-its-time 1961 B5000 with an O/S written in ALGOL.
Burroughs was one of the first to use something other than assembler for OS development. They chose a dialect of Algol.
In 1965 Multics(Project MAC, funded by ARPA) design began and PL/I was chosen to develop the OS. In 1969 Multics was opened for use at MIT, but there were frustrations and Bell Labs withdrew from Project MAC. Ken Thompson, Dennis Ritchie, Doug McIlroy, and J. F. Ossanna continued to seek the holy grail and Unics (later Unix) development began.
Multics History
Multics Failure?
Unix v. Multics
During the 1970's "Cold War" there was an effort to use the data security and parallel processing features of ALGOL 68 to create Secure/Capability based operating systems:
Cambridge CAP computer - All procedures constituting the operating system were written in ALGOL 68C, although a number of other closely associated protected procedures - such as a paginator - are written in BCPL. c.f. microsoft
Flex machine - The hardware was custom and microprogrammable, with an operating system, (modular) compiler, editor, garbage collector and filing system all written in Algol 68RS. A Linux port of this Algol68RS can be downloaded from compile can be downloaded from Sourceforge:algol68toc.
/* Interestingly portions of DRA's algebraically specified abstract machine Ten15 is still available, also from Sourceforge:TenDRA (for minux). Ten15 serves as DRA's intermediate language for compilers, and evolved to support C and Ada. Apparently an attempt was made to port FreeBSD/Unix using the TenDRA C compiler */
ICL VME - S3 programming language was the implementation language of the operating system VME. S3 was based on ALGOL 68 but with data types and operators aligned to those offered by the ICL 2900 Series. This OS is still in use as a Linux VM, and has some 100,000 users.
The Soviet Era computers Эльбрус-1 (Elbrus-1) and Эльбрус-2 were created using high-level language uЭль-76 (AL-76), rather than the traditional assembly. uЭль-76 resembles Algol-68, The main difference is the dynamic binding types in uЭль-76 supported at the hardware level. uЭль-76 is used for application, job control, system programming c.f. e2k-spec.
Maybe the US military was doing something similar somewhere. Anyone?
There were many 16-bit Forth systems where the interpreter and (fairly primitive) OS layer were written in Forth.
The original Mac OS was written in a mix of 68k ASM and a slightly extended Pascal.
ADA has been used to write several OS's.
But I'd guess that the dominant language used for OS development prior to C was IBM 360 assembly language.
That depends. The Amiga OS for example was originally written to a certain extent in BCPL, and you would imagine that many ancient operating systems were written in pure assembly language.
CP/M (which is kind of MS-DOS' predecessor) was written in PL/M, but MS-DOS was written in assembly for performance reasons. Here is something on MS-DOS: http://www.patersontech.com/Dos/Byte/InsideDos.htm
(Edited, not sure where I picked up this Fortran garbage.)
Operating systems "want" to be written in assembler. If you're starting from scratch, once you have the interrupt routines done, you can just keep on going and not get around to a high-level language interface.
Furthermore, assemblers like to evolve. Once you've covered the specified instruction set, it's convenient to add alias names for instructions that serve multiple purposes. Next come pseudo-instructions that can alias a couple machine instructions. Then it's nice to have an extensible facility for writing macro subroutines, to generate arbitrary sections of code that look like instructions. (Unlike C macros, this often may allow flow control and script-like programming.) Then, there are scoping rules to ensure identifiers are only used in a particular context.
Bit by bit, languages evolve. C didn't pop out of thin air. It was preceded by a generation or two of languages (Algol, BCPL) that evolved from high-level assemblers. Many platform-specific assembly languages were in fact reasonably nice. IBM still makes a mean assembler. (Of course, before that were not-so-nice assemblers, and before that were punch cards and toggle switches.)
More recently, GNU as has given assembly a bit of a bad name by being relatively primitive. Don't believe the scare tactics, though.
Related
I was looking into compiler bootstrapping, and I looked at how Golang implements bootstrapping from source, i.e., by building the last version of Golang implemented in C and using the generated executable to compile newer Go releases. This made me curious as to how the same could be done with C. Can you construct a C compiler on a computer with literally nothing present on it? If not, then how can I trust that the binary of the compiler I use doesn't automatically fill the binaries it compiles with spyware?
Related question, since the first C compiler was written in B and B was written in BCPL, what was BCPL written in?
Can you construct a C compiler on a computer with literally nothing present on it?
The main issue is how (in 2021) would you write a program for that computer! And how would you input it?
In the 1970s computers (like IBM 360 mainframes) had many mechanical switches to enter some initial program. In the 1960s, they had even more, e.g. IBM1620.
Today, how would you input that initial program? Did you consider using some Arduino ? Even oscilloscopes today contain microprocessors with programs....
Some hobbyists today have designed (and spent a lot of money) in making - a few years ago - computers with mechanical relays. These are probably thousands times slower than the cheapest laptop computer you could buy (or the micro-controller inside your computer mouse - and your mouse contains some software too).
You could also buy many discrete transistors (e.g. thousands of 2N2222) and make a computer by soldering them.
Even a cheap motherboard (like e.g. MSI A320M A-PRO) has today some firmware program called UEFI or BIOS. It is shipped with that program.... and rumored to be mostly written in C (several dozen of thousands of statements).
In some ways, computer chips are "software" coded in VHDL, SystemC, etc... etc...
However, you can in principle still bootstrap a C compiler in 2021.
Here is an hypothetical tale....
Imagine you have today a laptop running a small Linux distribution on some isolated island (à la Robinson Crusoe), without any Internet connection - but with books (including Modern C and some book about x86-64 assembly and instruction set architecture and many other books in paper form), pencils, papers, food and a lot of time to spend. Imagine that system does not have any C compiler (e.g. because you just removed by mistake the gcc package from some Debian distribution), but just GNU binutils (that is, the linker ld and the assembler gas), some editor in binary form (e.g. GNU emacs or vim), GNU bash and GNU make as binary packages. We assume you are motivated enough to spend months in writing a C compiler. We also assume you have access to man pages in some paper form (notably elf(5) and ld(1)...). We have to assume you can inspect a file in binary form with od(1) and less(1).
Then you could design on paper a subset µC of the C language in EBNF notation. With months of efforts, you can write a small assembler program, directly doing syscalls(2) (see Linux Assembly HowTo) and interpreting that µC language (since writing an interpreter is easier than writing a compiler; read for example the Dragon book, and Queinnec's Lisp In Small Pieces and Scott's programming language pragmatics book).
Once you have your tiny µC interpreter, you can write a naive µC compiler in µC (since Fabrice Bellard has been able to write his tinyC compiler).
Once you have debugged that µC compiler, you can extend it to accept all the syntax and semantics of C.
Once you have a full C compiler, you could improve it to optimize better, maybe extend it to accept a small subset of C++, and you might also write a static C code analyzer inspired by Frama-C.
PS. Bootstrapping can be generalized a lot - see Pitrat's blog on bootstrapping artificial intelligence (Jacques Pitrat, born in 1934, died in october 2019) and the RefPerSys project.
As Some programmer dude stated in a comment, since C is a portable programming language, you can use a compiler for a different platform to produce a cross-compiler that on that platform would produce executables for the target platform.
You then compile that same C compiler for the target platform on that host platform so that the result is an executable for the target platform.
Then you copy that compiler binary onto the target machine and from thereon it is self-hosting.
Naturally at some point in early history someone really had to write something in assembler or machine code somewhere. Today, it is no longer a necessity but a "life choice".
As for the "how can I trust that the binary of the compiler I use doesn't automatically fill the binaries it compiles with spyware?" problem has been solved - you can use two independent compilers to compile the cross-compiler from the same source base and the target and both of those cross-compilers should produce bitwise-identical results for the target executable. Then you would know that the result is either free of spyware, or that the two independent compilers you used in the beginning would infect the resulting executable with exact same spyware - which is exceedingly unlikely.
You can write a really feeble C compiler in assembly or machine code, then bootstrap from there.
Before programming languages existed you just wrote machine code. That was simply how it was done.
Later came assembler, which is like "easy mode" machine code, and from there evolved high-level languages like Fortran and BCPL. These were decoupled from the machine architecture by having a proper compiler to do the translation.
Today you'd probably write something in C and go from there, anything compiled is suitable, though "compiled" is a loose definition now that LLVM exists and you can just bang out LLVM IR code instead of actual machine code. Rust started in OCaml and is now "self-hosted" on top of LLVM, for example.
I would like to build an OS some time in the future, and now thinking of some light sketches on how it would be. I have pretty much been coding in C compiled for the Windows environment (and some little Java). I would have to recompile any of my C programs should I want to run it under Linux. So the binaries, the product of compilation, must be different for each operating system. If I design a totally new OS from scratch, for both hobby and academic purpose, without using the Linux kernel or any known base code of an OS, what I understand as to happen is that I cannot compile my C programs with GCC since my OS will not be among its target systems. Here my question written on the title emerges. Thanks in advance for any hints.
It depends. You could easily choose to re-use an existing compiler, such as the immemorial example GCC, and thus you would reap the benefits of an existing compiler. But there are some big provisos that must be cleared up.
Regards of whether or not you choose to build a new compiler, the challenge will remain in porting a C library. You technically can use C without a standard library (which is what the Linux kernel, or any self-hosted example for that matter, has to do, for example) but this is a ridiculous proposition for programs intended to run under an operating system, as most systems impose memory restrictions, etc, meaning that you cannot just have carte blanche in terms of using memory. Thusly, a C library call such as malloc is required.
Since any programs under your kernel (99% of your OS in all likelihood) will need a set of functions to link against, porting a C library is your biggest task. The C library is a huge monolith, and writing your own would be rather silly, especially with many implementations already available, the most well known being GCC's. So, the question you really should be asking is, do you want to write my own version of libc? (The answer is almost always no, and most alternative implementations are for niche use cases.) Plus, if you want to make your OS POSIX-compliant, then you'll have to implement more functions, adding to the hassle.
Whether you write your own compiler for your OS is a minor detail compared to which C library will be included with it. You can always use your own compiler with an already-written implementation of the C library.
My advice to your rather opinion-based question: no. Port an existing compiler such as GCC or clang, and then use that. Plus, that has several advantages:
Compatibility with existing tools and toolchains
A familiar program (no need for your users to learn how to use a new compiler)
They're open source - and in spite of that, you'd be insane to go at it alone. Heck, even Apple integrated two already existing compilers - GCC and clang - into their toolchains rather than do it themselves, and they're a billion-dollar company.
Take a look at this page. It demonstrates how to port GCC to your OS using Newlib as your C library.
No, you can just port an existing compiler. You can even choose an existing executable format, such as ELF, and use your standard GCC + GNU Binutils toolchain. You will need to port the standard library and C runtime, and you will need to write an ELF loader into your operating system.
I suspect the majority of the work will be in porting the C library.
A search turned up this page: Porting GCC to your OS
(1) No, you usually don't have to write your own compiler. Writing a good optimizing compiler can be actually big task which I would better avoid.
But in order to enable writing applications for your OS in some higher level language you will either need to provide
some (2.1) API emulation layer (so that code written and compiled for other OS can be run on your OS)
or you'll have to (2.2) port some existing compiler to your OS
or at least make your OS a new available (2.3) target platform in an existing compiler
or some other option I don't know about
The choices are multiple each with its own pros/cons.
Some examples (other then the obvious GCC already mentioned by #dietrich-epp, #sevenbits) to help you decide which way you want to follow:
(3.1) Free Pascal (see http://www.freepascal.org) compiler can be extended with another target platform
Free Pascal is a 32,64 and 16 bit professional Pascal compiler. It can target multiple processor architectures: Intel x86, AMD64/x86-64, PowerPC, PowerPC64, SPARC, and ARM. Supported operating systems include Linux, FreeBSD, Haiku, Mac OS X/iOS/Darwin, DOS, Win32, Win64, WinCE, OS/2, MorphOS, Nintendo GBA, Nintendo DS, and Nintendo Wii. Additionally, JVM, MIPS (big and little endian variants), i8086 and Motorola 68k architecture targets are available in the development versions
...
Source: http://www.freepascal.org
(3.2) Inferno Operating System (see http://www.vitanuova.com/inferno) has its own application language (see Limbo) with OS specific words, own compiler etc. Applications run in virtual machine (see Dis)
Inferno® is a compact operating system designed for building distributed and networked systems on a wide variety of devices and platforms. With many advanced and unique features, Inferno puts an unrivalled set of tools into your hands...Inferno can run as a user application on top of an existing operating system or as a stand alone operating system...
Source: http://www.vitanuova.com/inferno
(3.3) Squeak (see http://en.wikipedia.org/wiki/Squeak) is a self contained OS with graphics and everything. It uses Smalltalk-80 as the language. Compiler included, applications run in virtual machine (see Cog VM). The VM could be emitted as portable C code and then ported to a bare-bone hardware.
Squeak is a modern, open source, full-featured implementation of the powerful Smalltalk programming language and environment. Squeak is highly-portable, running on almost any platform you could name and you can really truly write once run anywhere. Squeak is the vehicle for a wide range of projects from multimedia applications and educational platforms to commercial web application development...
Source: http://www.squeak.org
(3.4) MenuetOS (see http://www.menuetos.net/) is 64bit OS written in assembly language. Flat Assembler (see FASM) compiler which can emit native binaries was ported to the OS including OS API and is included in basic installation. Later on C library was also ported
MenuetOS is an Operating System in development for the PC written entirely in 32/64 bit assembly language...supports 32/64 bit x86 assembly programming for smaller, faster and less resource hungry applications...Menuet isn't based on other operating system nor has it roots within UNIX or the POSIX standards. The design goal, since the first release in year 2000, has been to remove the extra layers between different parts of an OS, which normally complicate programming and create bugs...
Source: http://www.menuetos.net
(3.5) Google's Android OS (see Wikipedia: Android (operating system)) ported Java Virtual Machine (see Dalvik later replaced by Android Runtime) and provided OS APIs for the Java programming language, reusing existing compilers and IDEs just consuming the produced binaries
Android Runtime (ART) is an application runtime environment used by the Android mobile operating system. ART replaces Dalvik, which is the process virtual machine originally used by Android, and performs transformation of the application's bytecode into native instructions that are later executed by the device's runtime environment...
Source: http://en.wikipedia.org/wiki/Android_Runtime
There are many more useful examples available. Whether you have to or don't have to basically depends on the programming paradigm your new OS will introduce. Why you want to build it and how will it differ from the existing ones.
Examples for no are: (3.1), (3.4), (3.5)
Examples for yes are: (3.2), (3.3)
Are cores of OSs (device interaction level) really written in C, or "written in C" means that only most part of OS is written in C and interaction with devices is written in asm?
Why I ask that:
If core is written in asm - it can't be cross-platform.
If it is written is C - I can't imagine how it could be written in C.
OK. And what about I\O exactly - I can't imagine how can interaction with controller HDD or USB controller or some other real stuffs which we should send signals to be written without (or with small amount of) asm.
After all, thanks. I'll have a look at some other sources of web.
PS (Flood) It's a pity we have no OS course in university, despite of the fact that MIPT is the Russian twin of MIT, I found that nobody writes OSs like minix here.
The basic idea in Unix is to write nearly everything in C. So originally, something like 99% of it was C, it was the point, and the main goal was portability.
So to answer your question, interaction with devices is also written in C, yes. Even very low-level stuff is written in C, especially in Unix. But there are still very little parts written in assembly language. On x86 for example, the boot loader of any OS will include some part in assembler. You may have little parts of device drivers written in assembly language. But it is uncommon, and even when it's done it's typically a very small part of even the lowest-level code. How much exactly depends on implementations. For example, NetBSD can run on dozens of different architectures, so they avoid assembly language at all costs; conversely, Apple doesn't care about portability so a decent part of MacOS libc is written in assembly language.
It depends.
An OS for a small, embedded, device with a simple CPU can be written entirely in C (or C++ for that matter).
For more complicated OS-es, such as current Windows or Linux, it is very likely that there are small parts written in assembly. I would expect them most in the task scheduler, because it has some tricky fiddling to do with special CPU registers and it may need to use some special instructions that the compiler normally does not generate.
Device drivers can, almost always, be written entirely in C.
Typically, there's a minimal amount of assembly (since you need some), and the rest is written in C and interfaces with it. You can write functions in assembly and call them from C, so you can encapsulate whatever functionality you want.
By a little implementation-specific trickery, it can be possible to write drivers entirely in C, as it is normally possible to create, say, a volatile int * that will use a memory-mapped device register.
Some operating systems are written in Assembly language, but it is much more common for a kernel to be written in a high level language such as C for portability. Typically (although this is not always the case), a kernel written in a high level language will also have some small bits of assembly language for items that the compiler cannot express and need to be written in Assembler for some reason. Typical examples are:
Certain kernel-mode only instructions
to manipulate the MMU or perform
other privileged operations cannot be generated by a standard compiler. In this case the code must be written in assembly language.
Platform-specific performance optimisations. For example the X64 architecture has an endan-ness swapping instruction and the ARM has a barrel shifter (rotates the word being read by N bits) that can be used on load operations.
Assembly 'glue' to interface something that won't play nicely with (for example) C's stack frame structure, data formats or parameter layout conventions.
There are also operating systems written in other languages, for example:
http://en.wikipedia.org/wiki/Oberon_%28operating_system%29
http://en.wikipedia.org/wiki/Cosmos_%28operating_system%29
http://en.wikipedia.org/wiki/JX_%28operating_system%29
You don't have to wonder about questions like these. Go grab the linux kernel source and look for yourself. Most of the assembly is stored per architecture in the arch directory. It's really not that surprising that the vast majority is in C. The compiler generates native machine code, after all. It doesn't have to be C either. Our embedded kernel at work is written in C++.
If you are interested in specific pointers, then consider the Linux kernel. The entire software tree is virtually all written in C. The most well-known portion of assembly used in the kernel is entry.S that is specific to each architecture:
http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=blob;f=arch/x86/kernel/entry_64.S;h=17be5ec7cbbad332973b6b46a79cdb3db2832f74;hb=HEAD
Additionally, for each architecture, functionality and optimizations that are not possible in C (e.g. spinlocks, atomic operations) may be implemented in assembly:
http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=blob;f=arch/x86/include/asm/spinlock.h;h=3089f70c0c52059e569c8745d1dcca089daee8af;hb=HEAD
Do any proposed, or implemented languages fit in the same (enormous) niche as C, with the intention of being an alternative, while maintaining all the applicability to OS, high performance, embedded and other roles?
There are quite a number of languages that were explicitly designed to fit all of that niche:
BitC
Cyclone
Forth
Mesa
CPL
BCPL (simplified version of CPL, implementation language of MULTICS)
B (Ken Thompsons first try at a systems programming language, based loosely on BCPL, precursor to C)
Ada
Go
D
C++
Modula-2 (specifically designed for the Lilith personal computer as a successor to Pascal for systems programming, also used by IBM as the implementation language for the original OS/400)
Oberon (specifically designed as a simpler successor to Modula-2)
Component Pascal (object-oriented successor to Oberon, despite the name it is not a direct successor to Pascal)
Modula-3 (despite the name not a successor to Modula-2 but an independent development)
Sing# (the implementation language of Microsoft Research's Singularity Research OS)
Limbo (language for the Inferno operating system (successor to Plan 9 (successor to Unix)))
Ooc
Erlang (maybe not for operating systems, but embedded realtime systems, especially in the telco industry (phone switches etc.), also lately (somewhat surprising to Erlang's inventors, actually) web servers, databsase systems, etc.)
Interestingly, there are also a number of languages that were not specifically designed to fill that niche, but that have been very successfully used in that niche:
Smalltalk (several Smalltalk OSs, embedded systems, microcontrollers, realtime systems, most famous: the Tektronix TDS500 series of digital oscilloscopes)
Lisp (several Lisp OSs, embedded systems, microcontrollers, some NASA spacecraft)
Java (several Java OSs (JNode, NewOS), embedded systems, microcontrollers, smartcards)
C# (several OSs (Cosmos, SharpOS), Mono is used in High-Performance Computing)
Haskell (the House OS, the seL4 verified microkernel)
Pascal (MacOS)
There's also a lot of languages that have not yet been used in that niche, but that certainly could be. (Mostly that is because those language communities themselves have been so indoctrinated by the "you can only write operating systems in C" bullshit that they actually believe their own language to be unusable.)
Ruby
Python
ECMAScript (which is actually used for writing high-performance webservers lately)
[Note that for each one of the three categories I listed there are literally thousands more languages that fit in there.]
In fact, one sometimes gets the feeling that languages which are not specifically designed for, say, operating system programming are actually better for that kind of thing. Compare, for example, the level of innovation, the stability, number of security holes, performance in something like a Smalltalk OS from the 1970s and Windows or OSX from 2010.
Personally, I believe that this is based on some deep-seated myths in the systems programming community. They believe that systems programming in a language with, say, strong typing, type safety, memory safety, pointer safety, automatic storage management is impossible and that the only way to get performance or realtime guarantees is to forego powerful abstraction facilities. However, it turns out that when you try to design a programming language for humans instead of machines, then humans can actually understand the programs they wrote, find security holes, fix bugs and locate and fix performance bottlenecks much better in a 1 line monad comprehension than in a 100 line for loop.
For example SqueakNOS, which is a variant of the Squeak Smalltalk system that runs without an OS (in other words: it is the OS) has pretty much all of the features that you would expect from a modern OS (graphical user interface, ...) plus some that you don't (embedded scripting language that can modify every single piece of the OS at runtime) and weighs in at just 300k SLOC and boots in less than 5 seconds while e.g. Windows weighs in at 50 million SLOC.
The obvious one is C++.
Does everything you describe, but extends C quite a bit with other features (Object Oriented, etc.).
Another interesting system programming language from Google: Go
BitC is a specific attempt. Here's a great article on alternatives to C, and why they've failed.
Ada is probably the most widely used language in this space apart from C.
It is designed above all to produce reliable bug free code, but, most Ada compilers produce well optimised effiecient machine code as well.
For a while this language was compulsary for Department of Defence projects and it is still widly used in avaionics, radar, navigation and weapons control systems.
You could consider D. From the homepage:
D is a systems programming language. Its focus is on combining the power and high performance of C and C++ with the programmer productivity of modern languages like Ruby and Python. Special attention is given to the needs of quality assurance, documentation, management, portability and reliability.
The D language is statically typed and compiles directly to machine code. It's multiparadigm, supporting many programming styles: imperative, object oriented, and metaprogramming. It's a member of the C syntax family, and its appearance is very similar to that of C++.
Ada and in most cases Objective-C.
freepascal.
pascal was created even before C, when there was not enough RAM and CPU for virtual machines and is still used for exactly the same porpuses than C.
modern incarnations of pascal namely Delphi and freepascal added OO and generics, following the evolution C++ has represented.
they share many concepts and design like pointers, direct allocation deallocation of memory, direct call of ASM inside programs, they are so similar that is not unusual to load dll or c/c++ code in pascal programs and vice versa.
probably looking at ancient languages like Basic it is possible to find implementations that are fitting the same niche of c.
languages follow platforms...
Do any proposed, or implemented languages fit in the same (enormous) niche as C, with the intention of being an alternative, while maintaining all the applicability to OS, high performance, embedded and other roles?
OSs were historically implemented in assembler. Later on development shifted to C, which initially was a sort of macro assembler.
Now most OSs are written mostly in C because it is pretty much only language which maintains some sort of assembler backward compatibility (e.g. one can map one to one lion share of the assembler found in the hardware specs into C). And libc is the primary interface - often is the only interface - between kernel and user-space. And yet the interface covers not everything: some things in kernel has to be accessed directly as no standard interface is (yet) provisioned. E.g. one has to use a C struct to pass parameters/retrieve results to/from ioctl.
That means that the use of C in application development is in greater part pushed by the simple fact that if you use C you get automatically access to all the features of kernel (OS) which is also written in C.
Only language which can somehow compete with C is the language which is based/compatible with C. The sole alternative known to me is the C++. In older times there were also relatively popular translators like p2c (Pascal to C): developer programs in one language, but the source code is automatically translated into C for compilation. But the translators were rather buggy and without knowledge of C often programs couldn't be debugged. So if you have to know some C anyway, why bother with the translators.
I personally (and many other developers I'm sure) using various languages often stumbled upon the problem that the OS has a feature, but the language used doesn't provide any facility to access it. That I think is the major deterrent factor for other language development. Even if you have bright a idea for a new language (which is likely to be incompatible with C, otherwise idea wouldn't be that bright) you end up with the burden to reimplement interface to the pretty much whole OS (and various must-have application libraries).
As long as (1) C remain the sole language for system programming and (2) OS interfaces are still evolving, all non-C-compatible languages on the other side of fence, application development, would be at greater disadvantage.
P.S. Actually that is one of the molds I hope LLVM/clang might break. clang is implemented as a reusable library theoretically allowing to mix languages. E.g. main source file can be in one language (and parsed by one front-end), but the #includes could be in C (and parsed by the clang).
Scala Native tries to be the functional-programming & functional-objects evolution of C's niche. Scala Native generates hardware machine code instead of JVM. https://scala-native.readthedocs.io/en/v0.4.0/
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 9 years ago.
Improve this question
Why is C used for writing drivers and OS codes?
Is there a size problem?
Are there any drivers written in other languages?
Which language were XP, Vista, and Solaris written in?
C compiles down to machine code and doesn't require any runtime support for the language itself. This means that it's possible to write code that can run before things like filesystems, virtual memory, processes, and anything else but registers and RAM exist.
In safety-critical environments (think avionics, spacecraft, medical devices, transportation, control software for process control), systems (as well as drivers) are often written using Ada or even SPARK/Ada.
To clarify: C is usually understood to be fairly low level, and pretty much like a "macro language" for assembly itself, that's also where its power is coming from (speed, size, portability).
Ada, on the other, hand has been specifically designed for safety-critical applications with verifiability in mind, to quote Ada 2005 for Mission-Critical Systems:
Ada [9] is the language of choice for many critical systems due to its careful design and the existence of clear guidelines for building high integrity systems [10]
That's also where Ada's support for strong typing comes in, as well as a number of other important features (quoting design for safety):
Programming languages differ wildly in
their appropriateness for use in
safetyrelated systems. Carré et al.
identified six factors that influence
the suitability of a language for
high-integrity applications [Carré
1990]. These are:
Logical soundness
Complexity of definition
Expressive power
Security
Verifiability
Bounded time and space constraints
No standard programming language performs
well in all these areas although some
(such as Pascal and Ada) perform much
better than languages such as C or
C++. In highly critical applications
‘verifiability’ is of great
importance. Certain languages allow
powerful software verification tools
to be used to perform a wide range of
static tests on the code to detect a
range of programming errors.
[...] An
important issue in the selection of a
programming language is the quality of
the available compilers and other
tools. For certain languages validated
compilers are available. While not
guaranteeing perfection, validation
greatly increasing our confidence in a
tool. Unfortunately, validated
compilers are only available for a
limited number of languages, such as
Ada and Pascal. In addition to
compilers, developers of critical
systems will make use of a range of
other tools such as static code
analysis packages. The static tests
that can be performed on a piece of
code vary greatly depending on the
language used. To aid this process it
is common to restrict the features
that are used within certain languages
to a ‘safe subset’ of the language.
Well structured and defined languages
such as subsets of Ada, Pascal and
Modula-2 allow a great many tests to
be performed such as data flow
analysis, data use analysis,
information flow analysis and range
checking. Unfortunately many of these
tests cannot be performed on languages
such as C and C++ .
It would be really beyond the scope of this question to go into even more detail, but you may want to check out some of the following pointers:
Ada compared to C and C++
Ada vs. C
Quantifying the Debate: Ada vs. C++
Why choosing Ada as a teaching language? (Ada vs. C in University)
Comparing Development Costs of C and Ada (summary)
C / C++ / Java Pitfalls
& Ada Benefits
Is Ada a better C?
Ada, C, C++, and Java vs. The Steelman
Ada: Dispelling the Myths
Real-time programming safety in Java and Ada
If anyone wants to look into Ada some more, check out this: Ada Programming (wikibooks)
There are even programming languages that are specifically developed for highly critical applications, such as JOVIAL or HAL/S, the latter of which is used by the space shuttle program.
Is there any drivers written in any other languages?
I have seen some Linux drivers for special hardware being written in Ada, don't know about other operating systems though. However, such drivers usually end up wrapping the the C API.
Because C has the best combination of speed, low memory use, low-level access to the hardware, and popularity.
Most operating systems have a kernel written in C, and applications on top of that written in either C, C++, C# or Obj-C
C is by far the easiest language(other than assembly) to "get going" on bare bones hardware. With C, (assuming you have a 32bit bootloader such as GRUB to do the hard mode switching) all you must do is make a little crt0.asm file that sets up the stack and that's it(you get the language, not including libc). With C++ you must worry about dynamic casts, exceptions, global constructors, overriding new, etc etc.. With C# you must port the .Net runtime(which on it's own basically requires a kernel) and I'm not sure about Obj-C, but Im sure it has some requirements also...
C is simply the easiest language to use for drivers. Not only is it easy to get started with, but also it's easy to know exactly what happens at the machine level. Their is no operator overloading to confuse you and such. Sure it's handy in a "good" environment, but in Ring 0 where a bad pointer not only crashes your application, but usually results in a triple fault(reboot), blue screen, or kernel panic. You really like knowing what goes on in your machine..
"why we are using C language for writing drivers and OS codes.?"
So that programmers won't have to learn new syntax of each new assembly language for each new kind of machine.
"Is there any drivers written in any other languages?"
Historically, assembly languages. I don't remember if PL/S or BLISS could be used for drivers. Maybe B. In modern times, a few brave people use C++ but they have to be very careful. C++ can be used a bit more easily in user mode drivers in some situations.
Lisp machines had their operating systems written in Lisp, which shows that you don't have to use C or assembly. The Lisp machine business was destroyed by the availability of cheap PCs, whose operating systems were of course written in C and assembly.
C was one of the very first languages (that wasn't assembly) that was suitable for writing operating systems, so it caught on early. While other languages have appeared since that are also suitable for writing operating systems in, C has remained popular perhaps due to its long history and the familiarity programmers have with its structure and syntax.
C is also a language that teaches a lot about memory management and is low-level enough to show the barrier between hardware and software. This is something that is rare among many methodologies today, that have grown more towards abstraction way above anything at the hardware level. I find C is a great way to learn these things, while being able to write speedy code at the same time.
Remember that C was originally developed for writing operating systems (in this case - Unix) and similar low-level stuff. It is wery close to the system architecture and does not contain any extra features that we want to control, how they exactly work. However, please note that the rest of the operating system, including the programming libraries, does not have to be written in the same language, as the kernel. The kernel functions are provided through a system of interrupts and in fact such programming libraries can be written in any language that supports assembler snippets.
The most popular operating system nowadays are written in C: Windows, Linux and many other Unix clones, however this is not the rule. There are some object-oriented operating systems, where both the kernel and the programming interface are written in an objective language, such as:
NeXTSTEP - Objective-C
BeOS - C++
Syllable - C++
See: Object-oriented operating system on Wikipedia
Note that in Linux, it is possible to write kernel drivers in the languages other than C (however, it is not recommended). Anyway, everything becomes a machine code when it comes to running it.
"C compiles down to machine code and doesn't require any runtime support for the language itself."
This is the best feature of C
It's my belief that languages like Python, Java, and others are popular mainly because they offer extensive standard libraries that allow the programmer to code a solution in less lines. Literally a ruby programmer can open and read a file in one line where in C it takes multiple lines. However beneath this abstraction are multiple lines. Therefore the same abstraction be done in C and it's recommended. Oddly it seems the C philosophy is not to reduce the total lines of code so there is no organized effort to do so. C seems to be viewed as a language for all processor chips and naturally this means that it's hard to create any 'standard' abstracted one line solutions. But C does allow you to use #ifdef preprocessor commands so in theory you can have multiple variations of an implementation for multiple processors and platforms all on one header file. This can't be the case for python, or java. So while C does not have a fancy standard library it's useful for portability. If your company wants to offer programs that run on computers, embedded, and portable devices then C is your choice language. It's hard to replace C's usefulness in the world.
As another note for machines that have drivers in other languages, there is the SunSpot robotics platform. Drivers for devices that are connected (sensors, motors, and everything else that can communicate via the I/O pins) are written in Java by the user.