Which C version is used in the Linux kernel?

后端 未结 3 1252
被撕碎了的回忆
被撕碎了的回忆 2020-12-13 04:06

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

相关标签:
3条回答
  • 2020-12-13 04:37

    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.

    0 讨论(0)
  • 2020-12-13 04:41

    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).

    0 讨论(0)
  • 2020-12-13 04:53

    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".

    0 讨论(0)
提交回复
热议问题