47

Does the Linux kernel use only the old C90 syntax or has it been optimized with C99 / C11 features?

I was wondering if the newest versions of C are used when possible.

Acorn
  • 23,483
  • 4
  • 35
  • 66
PerrierCitror
  • 1,869
  • 3
  • 17
  • 34

4 Answers4

62

See the bottom of this answer for updates.

The Linux kernel coding style document doesn't say much about the use of C90 vs. C99.

It suggests the use of typedefs for "New types which are identical to standard C99 types, in certain exceptional circumstances" while discouraging typedefs in most cases. Note that this doesn't actually imply depending on the C99 standard, since such typedefs can be defined in pure C90.

Later in the discussion of typedefs, it says:

In certain structures which are visible to userspace, we cannot require C99 types and cannot use the u32 form above. Thus, we use __u32 and similar types in all structures which are shared with userspace.

The implication is that the kernel must work with user code written in C90.

The only other reference to C99 is:

Linux style for comments is the C89 "/* ... */" style.
Don't use C99-style "// ..." comments.

The top-level kernel documentation web page refers to the C99 standard as the "current version of the C programming language" (which was probably correct when it was written; the current official version is now C11).

Looking at the kernel sources, there are 1766 Makefiles in the directory tree (as of the last time I checked it out from git). Of these, only 3 refer to the -std=gnu99 gcc option, and those are for tools, not for the main kernel itself (and 2 more refer to -std=gnu89, which is currently the default). This implies that the vast majority of the Linux kernel sources are written to be compiled with options that cause it to (mostly) conform to the C89/C90 standard with some GNU-specific extensions. Some of these extensions are C99 features.

The coding conventions for the Linux kernel are largely controlled by Linus Torvalds. This message of his from April 2012 shows his personal attitude regarding (some) C99-specific features:

On Wed, Apr 11, 2012 at 9:28 PM, Oleg Nesterov <oleg@redhat.com> wrote:
>
> Agreed. But,
>
>        error: 'for' loop initial declaration used outside C99 mode
>
> we should change CFLAGS, I guess. BTW, personally I'd like very much
> to use "for (type var; ...")" if this was allowed.

The sad part is that if we allow that, we also get that *other* insane
C99 variable thing - mixing variables and code.

I *like* getting warnings for confused people who start introducing
variables in the middle of blocks of code. That's not well-contained
like the loop variable.

That said, most of the stuff in C99 are extensions that we used long
before C99, so I guess we might as well just add the stupid flag. And
discourage people from mixing declarations and code other ways (sparse
etc).

                         Linus

Bandrami's answer is partially correct in pointing out that many of the feature added by C99 are in the library. For the most part, library features are irrelevant to the Linux kernel. The kernel does not run in a "hosted" environment, and it doesn't have access to most of the C standard library; for example, you can't use printf in the kernel (there's a similar printk function used for logging and debugging). But that's only part of the picture. Many of the features added by C99 are in the language proper (i.e., the part described by section 6 of the ISO C standard), and are at least potentially applicable to kernel source code.

UPDATE :

RudolfW points out this commit, which makes the -std=gnu89 configuration (C 89/90 with GNU extensions) explicit.

End result: we may be able to move up to a newer stdc model eventually, but right now the newer models have some annoying deficiencies, so the traditional "gnu89" model ends up being the preferred one.

This was in response to a change in gcc release 5, which changed the default standard option from -std=gnu90 to -std=gnu11 (skipping -std=gnu99). The top-level Makefile in the linux git repo still refers to -std=gnu89 as of Fri 2020-09-18. (-std=gnu89 and -std-gnu90 are equivalent.)

Marc.2377's answer cites a document that's probably more directly relevant. It explicitly says that "the kernel is typically compiled with gcc under -std=gnu89".

Keith Thompson
  • 242,098
  • 41
  • 402
  • 602
  • 2
    See also [this commit](http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=51b97e354ba9fce1890cf38ecc754aa49677fc89) - they are now explicitly using C90 with GNU extensions because an immediate transition to C99/C11 might not yield fully reliable results. – RudolfW Feb 02 '15 at 22:37
  • This answer does not seem up to date. See Marc's answer https://stackoverflow.com/a/58313785/9305398 – Acorn Sep 19 '20 at 22:02
  • @Acorn How is it not up to date? (I edited the last paragraph after you posted your comment but before I saw it, but I believe it was already current and correct. Marc's answer does add a link to a document I hadn't seen before. – Keith Thompson Sep 19 '20 at 23:54
  • @KeithThompson The answer starts linking a document that is not really relevant (the style guide), then continues trying to infer an answer from Makefiles, commits and emails. That information is a good analysis, but if something is documented, one should refer to that instead of implementation details or trying to infer things from other sources of information. – Acorn Sep 20 '20 at 00:47
  • @Acorn I'd say it's incomplete, not out of date. – Keith Thompson Sep 20 '20 at 00:54
  • 1
    @KeithThompson It is out of date because that document seems to be new, so this answer was OK before. – Acorn Sep 20 '20 at 00:56
  • @Acorn I just added a citation to Marc's answer. – Keith Thompson Sep 20 '20 at 00:59
  • In case anyone is interested, I added an [answer](https://stackoverflow.com/a/70981967/2965879) below that references a relatively recent discussion of LKML that's broadly on this topic. – Axel Feb 04 '22 at 05:51
12

As of now, the document at https://www.kernel.org/doc/html/latest/process/programming-language.html says:

The kernel is written in the C programming language [c-language]. More precisely, the kernel is typically compiled with gcc [gcc] under -std=gnu89 [gcc-c-dialect-options]: the GNU dialect of ISO C90 (including some C99 features).

Marc.2377
  • 6,811
  • 6
  • 52
  • 85
0

Stumbled over this while checking why the kernel isn't requiring C99 after 22+ years. There are parts of C99 used here and there in the kernel, but guarded by #ifdefs.

In any case, the following discussion (Sept. 2021) between Linus and some GCC people gives some relevant context, although it's mostly about standard-mandated header-includes (like <stdint.h>) and not so much about C language-features.

I find it a pity that the thread petered out, particularly the C99-<stdint.h> case with fixed-width integer types would be really helpful IMO.

More generally, now that the kernel also supports being built by Clang, it'd be great to move to a standard (by which I mean ISO C) baseline, rather than effectively a GNU-based one. And a more than 20 year old standard should really be enough IMO, even for the kernel...

Axel
  • 576
  • 4
  • 9
-10

There isn't really an answer because your question makes faulty assumptions. The C language versions assume the existence of a platform, but OS kernels like Linux are the platform (or at least a large part of it), so they don't have a "version" in that sense.

In terms of the parser's definition of the language, Linux is written in whatever a the concurrent gcc/icc/etc. will support, which as of now is C99. But like I said, the differences between C90 and C99 are based on the kernel and the library so they don't really apply to the kernel to begin with. (The only exception I can think of is anonymous functions, which the kernel doesn't use.)

Most of the day-to-day things you know about C are actually from the library, which depends on the kernel. So when you're programming a kernel, you're actually dealing with a much different set-up than when you are writing a normal C program.

Bandrami
  • 3,894
  • 1
  • 12
  • 11
  • 5
    That's incorrect. There are a number of *language* changes between C90 and C99, such as variable length arrays, `long long`, mixed declarations and statements, `_Bool`, and so forth. And I'm not sure what you mean by "anonymous functions"; there's no such feature in C90, C99, or C11. – Keith Thompson Dec 16 '13 at 00:03
  • @Keith can you then give an answer to my question ? – PerrierCitror Dec 16 '13 at 01:12
  • @Keith, the kernel has to do its own typing because all of those "language" features are implemented in the library, not the compiler (check the typedefs in the source tree some time). And, yes, the anonymous functions I was thinking of were a gcc extension; oops. – Bandrami Dec 16 '13 at 05:37
  • 3
    None of the features I mentioned are implemented in the library. None of them are typedefs. – Keith Thompson Dec 16 '13 at 05:40
  • 5
    This is wrong and misleading. There are loads of differences between C90 and C99 which have nothing to do with the standard library. Also, the standard doesn't depend on a "platform". It describes syntax and abstract semantics. It's not true either that Linux is written in C99, because it relies on quite a few non-standard GNU extensions. –  Dec 18 '13 at 17:55