引用了外部内联函数,但未定义

extern inline function was referenced but not defined

本文关键字:未定义 函数 外部 引用      更新时间:2023-10-16

我有一个函数(我们称之为void foo(void) {}),我希望它是内联的。但我在文件中定义了它.cpp。
我无法将函数移动到标题,因为它正在使用.cpp中的其他函数。



编辑:
下面的代码就像真正的代码一样,不使用C ++功能。我可以清楚地补充:

#ifdef __cplusplus
extern "C"
#endif

如果我想将下面的代码转换为 c99,我只需要更改我的项目属性(或 makefile,如果您愿意)而不是代码。我也在问 c++,因为它可以解决我的问题,而 c99 不能。
因此,我问题中的 C 和 C++ 标签是合理的。 代码是可移植
的 请参阅: 何时在C++中使用外部"C"?



编辑#2好的,
我知道我必须foo()定义放在头文件中。如何在不将它们移动到头文件的情况下从foo()调用func_a()func_b()?有什么解决方法吗?



示例
文件.c/.cpp:

int    func_a (int a,    int b,    int c)    {/*...*/};
double func_b (double a, double b, double c) {/*...*/};
void   foo    (int a, double b) { // unction definition
//...
int myInt = func_a(a, 2, 3);
//...
double myDouble = func_b(1.5f, b, 3.5f);
//...
}

文件.h:

// Something before.
void foo (int a, double b); // function declaration
// Something after.



我想指出:

  • 我正在使用Visual Studio 2015。
  • 我正在写一个比较大的项目(~7000行代码)。它是物理系统的模拟。
  • file.h包含在许多其他编译单元中。
  • foo(int, double)很小,它从file.cpp调用其他函数
  • 由于优化原因,我想使foo(int, double)内联(我最终将使用__forceinline__)
  • 我在我的程序中多次打电话给foo()。此外,它在几个while循环中使用(每个循环100k +迭代),因此让这个符号foo()内联是很广阔的。
  • 我厌倦了仅标题库。



我尝试:
file.c/.cpp:

extern inline
void   foo    (int a, double b) {*...*}; // Definition

文件.h:

extern inline
void   foo    (int a, double b); // Declaration

但我不断收到警告:

warning : extern inline function "foo" was referenced but not defined

我不明白为什么我会收到这个警告。



有没有办法:

  • 在我的.cpp文件中保留foo()的定义?但仍然使其内联
  • foo()移到file.h,保持func_a()func_b()file.cpp内,但使func_a()符号和func_b()符号对foo()"可见"(而且只对foo()!)从file.cpp
  • 还有其他解决方法吗?


Sory 我还在学习 cpp,我不知道我的问题是否清楚,或者是否可以从.cpp文件中内联函数。

在C++中,inline关键字的意思是:

函数
  • 的主体必须存在于使用该函数的每个源文件中。
  • 所有源文件中函数的"主体"必须逐个令牌和逐个实体相同。
  • 编译器和链接器必须确保它们对具有这些"多个主体"的函数感到满意

这就是它所做的一切。实际上,这意味着它启用并强制您将函数体放入头文件中。

关键字本身与函数内联本身无关。只是如果编译器希望能够内联函数的主体,那么在编译调用代码时必须有权访问它;换句话说,函数的主体必须位于同一源文件或该源文件包含的头文件中。

如果要使编译器能够在所有调用站点中内联函数,并且这些调用站点发生在多个源文件中,则必须将函数放入头文件中(并将其标记为inline)。

另一方面,链接器也可以进行内联,称为链接时间代码生成或整个程序优化或类似的东西(取决于工具链的供应商)。启用此操作将

  1. 延长构建时间,以及
  2. 允许链接器跨源文件将函数内联到调用站点中

因此,要内联函数,您有两种选择。将函数放入头文件中,或者启用并依靠链接时间优化来为您内联它。


在您的特定情况下,要使用__forceinline__,您将在头文件中定义foo。这需要定义foo才能看到func_afunc_b的声明。为了防止命名空间污染,您可以在foo范围内声明这些函数:

inline void foo(int a, double b) { // function definition
int func_a(int, int, int);
double func_b(double, double, double);
//...
int myInt = func_a(a, 2, 3);
//...
double myDouble = func_b(1.5f, b, 3.5f);
//...
}