我是否应该故意在C99中跨翻译单元内联函数

时间:2014-08-20 22:04:08

标签: c c99 inline-functions

在我的问题中,我最初问了这四个问题

  1. 在C99编译器中,在内联翻译单元时是否定义了inline实现的行为?
  2. 如果是,应该避免吗?
  3. 还有其他一些普遍接受的方法吗?
  4. 如果我的inline函数没有在任何地方内联,我至少会得到某种链接器错误吗?
  5. 在我的OP之后,我发现第一个问题已在以下主题中详细讨论过:

    关于这个主题还有更多主题,但这两个似乎在头上打了一针。

    因此,基于这两个讨论,我们可以看到问题1的答案是肯定的。编译器肯定有一些自由W.R.T.他们如何处理inline说明符。

    我们还看到,为了实现这一目标,inline函数必须在标题中定义。

    然后,存在以下选项:

    1. 标题中的函数定义可能有static说明符。
    2. 如果标头定义没有static说明符,则可以通过extern在一些公共头文件中声明,调用该函数的所有C文件也将#include
    3. 如果未使用方法2和方法3,方法4将在每个希望调用它的C文件中通过inline声明此extern函数。
    4. 所以,既然所有这些解释都已经解决了,我想把这个问题重新集中在我的原始项目#2和#3上 - 我是否应该这样做,如果是这样的话,那是什么?最可接受的方式?

      我应该这样做 - 还是应该尽可能避免这种情况?

      考虑我的应用程序 - 我在驱动程序中有一个单行函数,经常被调用(≈几百次/秒),但只有3或4个其他地方。因此,使用inline不会导致代码膨胀 - 实际上结果可以忽略不计。 Gregory Pakosz概述了何时使用inline函数以及何时不能使用this answer。因此,如果这是在一个翻译单元中使用的一个函数,那么答案将非常清楚。 但那不是我要求的

      在这种情况下,我不需要来内联此功能。但应该我?我可能永远不会注意到任何性能差异,因为我只是介绍了这一个功能。但我想弄清楚我是否应该在所有类似情况下将其作为我的一般做法。如果我内联频繁调用的短函数,我可能会看到性能提升。 (我的运行时环境是低功耗16位RISC MCU - 这可能是一个重要的细节。)

      问的原因是因为程序员之间似乎存在分歧。出于某种原因,是否错误的礼仪在翻译单元中内联函数(无论你怎么做),如果是这样,为什么?

      假设我在翻译单元中执行内联函数,那么最不可信或最可接受的方式是什么?

      static置于标题中似乎运行良好,可能是最便携的方法。 pts在评论中和buzz在答案中指出了这一点。从表面上看,似乎我正在使用static来促进全球使用 - 这是疯了!但我想我可以更正确地思考这个问题:内联这个函数的每个函数都有自己的静态副本,好像它在每个相应的C文件中定义为static inline一样。如果这种理解是正确的,那么行为似乎总是可预测的 - 如果翻译单元中有两个具有相同名称的函数,则链接器必须通知我。

      我不确定如何通过标题中的extern声明功能。 6.7.4中的措辞是另一个翻译单元中的外部定义是“不被禁止的”。

1 个答案:

答案 0 :(得分:2)

我认为你的driver.h应该是这样的:

static inline void foo(void)
{
    <one line>;
}

并且你的bar.c不需要extern inline void foo(void);,只需致电foo();,它就可以了。

至于If my inline function doesn't get inlined everywhere like it should - would I at least get some sort of linker error warning me that a certain reference couldn't be found

在编译时必须明确使用优化选项,然后您将内联函数实际内联。 gcc bar.c -O2。并且您可以使用objdump检查代码的汇编代码,您会发现内联函数被内联,而不是调用foo,但会在那里进行内联。