1

What is the point of having header files in C, if the header file not only includes prototypes of functions but also complete functions? I came across the file kdev_t.h in the linux source, which had the following:

    static inline dev_t new_decode_dev(u32 dev)
    {
         unsigned major = (dev & 0xfff00) >> 8;
         unsigned minor = (dev & 0xff) | ((dev >> 12) & 0xfff00);
         return MKDEV(major, minor);
    }

Why the .h extension? This question refers to classes in C++ but I'm not sure if the same principle applies here.

Community
  • 1
  • 1
ssh
  • 369
  • 7
  • 7
  • 3
    You may find [**this question and its accepted answer**](https://stackoverflow.com/questions/23699719/inline-vs-static-inline-in-header-file) an interesting read. – WhozCraig Aug 30 '14 at 12:10
  • Yes, it's basically the same as in your link. – mafso Aug 30 '14 at 12:14
  • Thanks @WhozCraig, that seems to be a clearer explanation. – ssh Aug 30 '14 at 12:16
  • In case you were wondering why I didn't mark it as a duplicate, because that question/answer explains *what* is going on (and pretty well at that), but not fully elaborating *this* question: *Why* (as in, why would someone do this in a .h file purposely). – WhozCraig Aug 30 '14 at 12:24

1 Answers1

1

I don't have any sources to back me up but I think it's a combination of the following reasons:

  1. Optimization. It's small enough that it would make optimization easier if the complete implementation was available to the compiler. Some of these small functions are called very often in the kernel that a cost of a branch can quickly add up. In your example, the code really only does some bit shifting tricks - not worth warranting a whole function call to another object file. With features like LTO though, I'm not so sure this is relevant.
  2. Macros are a pain for anything longer than a one-liner. Sometimes writing a separate function is a little overkill but the task is too long to fit in a (human-readable) macro. Macros also come with their own set of headaches. static inline functions provide essentially the same performance benefits as a macro but also maintains human readability.
  3. Empty implementations. The kernel is very configurable and you see a lot of #ifdefs for options. Sometimes, if a kernel function is disabled, we still want the functions to be callable but just return an error. These empty implementations are best placed in the header files instead of the object files so the kernel doesn't have to run the compiler on every single C file in the source tree. In other words, we improve compile times. Obviously there are also run-time optimizations where the compiler can know in advance on where dead code lie.

I think a combination of the 3 reasons above is the reason why Linux puts some small functions in the header file.

tangrs
  • 9,709
  • 1
  • 38
  • 53