内联函数和静态内联函数之间的区别
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 中定义了链接器错误,你会预料到它。我认为不需要诊断,但对链接器来说并不困难。以上是关于内联函数和静态内联函数之间的区别的主要内容,如果未能解决你的问题,请参考以下文章