为什么头文件包含完整的代码实现?

时间:2014-08-30 11:54:30

标签: c linux-kernel linux-device-driver

如果头文件不仅包括函数原型而且包括完整函数,那么在C中使用头文件有什么意义呢?我在linux源代码中遇到了文件kdev_t.h,其中包含以下内容:

    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);
    }

为什么.h扩展名? This问题是指C ++中的类,但我不确定这里是否适用相同的原则。

1 个答案:

答案 0 :(得分:0)

我没有任何消息来支持我,但我认为这是以下原因的组合:

  1. 优化。它足够小,如果编译器可以使用完整的实现,它将使优化更容易。这些小函数中的一些在内核中经常被调用,分支的成本可以快速累加。在你的例子中,代码实际上只做了一些改变技巧 - 不值得保证对另一个目标文件的整个函数调用。虽然有像LTO这样的功能,但我不确定这是否相关。
  2. 对于任何比单线更长的东西来说,宏是一种痛苦。有时候编写一个单独的函数有点过分,但是任务太长而无法适应(人类可读的)宏。宏也有各自令人头疼的问题。 static inline函数提供与宏相同的性能优势,但也保持人类的可读性。
  3. 空实施。内核非常易于配置,您可以看到很多#ifdef个选项。有时,如果禁用了内核函数,我们仍然希望函数可以调用,但只返回错误。这些空实现最好放在头文件而不是目标文件中,因此内核不必在源树中的每个C文件上运行编译器。换句话说,我们改进了编译时间。显然还有运行时优化,编译器可以事先知道死代码所在的位置。
  4. 我认为上述三个原因的组合是Linux在头文件中放置一些小函数的原因。