内联函数和静态内联函数之间的区别

Posted

技术标签:

【中文标题】内联函数和静态内联函数之间的区别【英文标题】:Difference between an inline function and static inline function 【发布时间】:2012-10-01 22:01:20 【问题描述】:

谁能告诉我内联函数和静态内联函数有什么区别?

在哪些情况下我应该更喜欢静态内联而不是内联?

我问这个问题是因为我有一个内联函数,在链接过程中我遇到了编译问题 (relocation error:... symbol has been discarded with discarded section ...)。我把它变成了一个正常的功能,它起作用了。 现在我的一些前辈告诉我尝试使用静态内联。 以下是我的功能:

inline void wizSendNotifier (const char* nn_name, bpDU* arg=0, int aspect = -1)

   wizuiNotifier* notifier = ::wizNtrKit.getNotifier (nn_name);
   notifier->notify (arg, aspect);

这不在一个类中。这是在头文件中!

我猜对静态函数的调用应该只在定义它的特定 TU 中完成。

由于我的函数位于头文件中,如果我将其设为静态,是否会出现这种情况,即我在哪里包含该头文件,静态函数可以在该翻译单元中使用?

【问题讨论】:

这个函数在一个类里面吗?也请张贴其声明。 ::wizNtrKit 是静态对象吗?它的联系是什么? 还有,函数出现在哪里?头文件,源文件?包含多少个源文件? 函数出现在头文件 steve 中。包含头文件的源文件大约有 50 个 【参考方案1】:

非静态inline 函数声明指的是每个使用它的翻译单元(源文件)中的相同函数。

单一定义规则要求函数定义的主体在包含它的每个 TU 中都是相同的,“相同”的定义较长。如果源文件都使用相同的标头,并且函数不使用任何具有内部链接的全局名称(包括static 函数)或任何在不同 TU 中定义不同的宏,则通常可以满足此要求。

我不记得以前遇到过那个特定的链接器错误,但至少有可能是这些限制之一负责。满足要求是您的责任:未定义的行为,如果您不这样做,则不需要诊断。

static inline 函数声明指的是每个翻译单元中的不同函数,恰好具有相同的名称。它可以使用 static 全局名称或在不同 TU 中不同的宏,在这种情况下,该函数在不同 TU 中的行为可能不同,即使它在头文件中的定义“看起来相同”。

由于这种差异,如果函数包含任何static 局部变量,那么它的行为会根据它是否为static 而有所不同。如果是static,那么每个TU 都有自己的函数版本,因此也有自己的static 局部变量副本。如果只有inline,那么所有TU使用的static局部变量只有一份副本。

【讨论】:

注意:在static函数的情况下,inline位失去其语义意义(如果该函数定义出现在多个TU中也没关系); inline 唯一保留的只是对编译器的提示,几乎忽略了。 是的,我所说的inline 函数也适用于既不是static 也不是inline 的函数声明,除了单一定义规则要求。与其要求每个 TU 中的定义相同,不如只要求一个 TU 包含一个定义。鉴于提问者的代码在删除inline 时有效,我怀疑这里发生了一些有趣的事情——如果在多个 TU 中定义了链接器错误,你会预料到它。我认为不需要诊断,但对链接器来说并不困难。

以上是关于内联函数和静态内联函数之间的区别的主要内容,如果未能解决你的问题,请参考以下文章

C内联函数的内外链接的区别

内联函数与宏的区别

在 Render 函数 React js 中编写内联函数方法与普通方法之间的区别

深入探讨 内联函数和宏定义的区别

内联函数和宏定义的区别和联系

类中的静态内联函数