好的,在阅读VivienG's link后,我想我已经理解了这个错误消息背后的确切原因。这是令人困惑和误导性(至少对我来说,如果你有只有一个翻译单元应该不会发生),但它是可能的解释:
假设编译器不希望实际直列代码,它必须知道该函数的放置位置,尤其是在多个翻译单元中使用时。
传统方法是创建多个副本,每个翻译单元一个(或至少对于使用它的单元)。
这可能会导致问题,例如,当试图做一些函数指针比较(仍然留下了为什么你会这样的问题)。
为了解决这个问题(和其它问题,我可能没有在这里列出),他们已经想到了一些实际上是相当整齐(虽然 - 如前所述 - 在我看来误导)解决方案:
你以您知道的方式将函数声明为inline
,但同时告诉编译器将非内联版本放入extern
关键字的位置。
所以,在你的榜样,你会保持你的功能,就是,把它放在一个头文件(因此它被称为地方它会被使用):
inline int foo(void)
{
return 10 + 3;
}
另外,告诉编译器在哪里放置非内嵌版本,你必须在一个转换单元中添加更多的“前进”的声明:
extern inline int foo(void);
所以整个概念相比,经典的职能基本上是相反的:把实施在头文件中,然后在一个文件中进行简短的声明。
如前所述,在使用-O3
参数时,所有标记为inline
的代码实际上是内联的,不会导致问题发生。
https://gcc.gnu.org/onlinedocs/gcc/Inline.html – Ashalynd 2014-10-22 08:34:16
@Ashalynd答案可能在某处,但它是什么? – harold 2014-10-22 08:36:06
我想知道'extern'是否需要GCC或C标准的一部分。我相信C99中增加了“内联”,但我不知道它是如何影响链接的。 – 2014-10-22 08:38:27