外部内联函数被引用但未定义
extern inline function was referenced but not defined
我有一个函数(我们称之为 void foo(void) {}
),我希望它成为 inline.But 我在 .cpp 文件中定义了它。
我无法将该函数移动到 header,因为它正在使用 .cpp 中的其他函数。
编辑:
下面的代码就像真正的代码一样没有使用 C++ 功能。我可以清楚地补充:
#ifdef __cplusplus
extern "C"
#endif
如果我想将下面的代码转换为 c99,我只需要更改我的项目属性(如果您愿意,也可以更改 makefile)不是代码。我也在问关于 c++ 的问题,因为它可以解决我的问题,而 c99 不能。
因此我的问题中的 C 和 C++ 标签是合理的。代码是可移植的
参见:When to use extern "C" in C++?
编辑 #2
好的,我知道我必须将 foo()
定义放在 header 文件中。如何从 foo()
中调用 func_a()
和 func_b()
而不将它们移动到 header 文件?有什么解决方法吗?
示例
file.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);
//...
}
file.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()
不是内联是可扩展的。
- 我厌倦了 header-only 图书馆。
我试过:
file.c/.cpp:
extern inline
void foo (int a, double b) {\*...*\}; // Definition
file.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()
保留在[=23=]内,但使func_a()
和func_b()
符号 "visible" 从 file.cpp
到 foo()
( ! 并且只到 foo()
! )
- 还有其他解决方法吗?
对不起,我还在学习 cpp,我不知道我的问题是否清楚,或者是否有可能从 .cpp 文件内联函数。
在 C++ 中,inline
关键字表示:
- 函数体必须出现在每个使用该函数的源文件中。
- 所有源文件中的函数 "bodies" 必须逐个标记和逐个实体相同。
- 编译器和linker 必须确保他们对具有这些 "multiple bodies"
的函数没有问题
这就是它所做的一切。实际上,这意味着它启用并强制您将函数体放入头文件中。
关键字本身与函数内联本身无关。只是如果编译器想要能够内联函数体,它必须在编译调用代码时访问它;换句话说,函数体必须在同一个源文件中或在该源文件包含的头文件中。
如果你想让编译器在所有调用点内联函数,并且这些调用点出现在多个源文件中,你必须将函数放入头文件(并将其标记为 inline
)。
另一方面,linker也可以做内联,叫做Link-Time Code Generation or Whole Program Optimization或类似的东西(取决于您的工具链供应商)。启用此功能将
- 延长构建时间,并且
- 允许 link 使用者将函数内联到调用站点 跨源文件
因此,要内联函数,您有两种选择。要么将函数放入头文件,要么启用并依赖 link-time 优化为您内联它。
在您的特定情况下,要使用 __forceinline__
,您需要在头文件中定义 foo
。这需要 foo
的定义才能看到 func_a
和 func_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);
//...
}
我有一个函数(我们称之为 void foo(void) {}
),我希望它成为 inline.But 我在 .cpp 文件中定义了它。
我无法将该函数移动到 header,因为它正在使用 .cpp 中的其他函数。
编辑:
下面的代码就像真正的代码一样没有使用 C++ 功能。我可以清楚地补充:
#ifdef __cplusplus
extern "C"
#endif
如果我想将下面的代码转换为 c99,我只需要更改我的项目属性(如果您愿意,也可以更改 makefile)不是代码。我也在问关于 c++ 的问题,因为它可以解决我的问题,而 c99 不能。
因此我的问题中的 C 和 C++ 标签是合理的。代码是可移植的
参见:When to use extern "C" in C++?
编辑 #2
好的,我知道我必须将 foo()
定义放在 header 文件中。如何从 foo()
中调用 func_a()
和 func_b()
而不将它们移动到 header 文件?有什么解决方法吗?
示例
file.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);
//...
}
file.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()
不是内联是可扩展的。 - 我厌倦了 header-only 图书馆。
我试过:
file.c/.cpp:
extern inline
void foo (int a, double b) {\*...*\}; // Definition
file.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()
保留在[=23=]内,但使func_a()
和func_b()
符号 "visible" 从file.cpp
到 - 还有其他解决方法吗?
foo()
( ! 并且只到 foo()
! )
对不起,我还在学习 cpp,我不知道我的问题是否清楚,或者是否有可能从 .cpp 文件内联函数。
在 C++ 中,inline
关键字表示:
- 函数体必须出现在每个使用该函数的源文件中。
- 所有源文件中的函数 "bodies" 必须逐个标记和逐个实体相同。
- 编译器和linker 必须确保他们对具有这些 "multiple bodies" 的函数没有问题
这就是它所做的一切。实际上,这意味着它启用并强制您将函数体放入头文件中。
关键字本身与函数内联本身无关。只是如果编译器想要能够内联函数体,它必须在编译调用代码时访问它;换句话说,函数体必须在同一个源文件中或在该源文件包含的头文件中。
如果你想让编译器在所有调用点内联函数,并且这些调用点出现在多个源文件中,你必须将函数放入头文件(并将其标记为 inline
)。
另一方面,linker也可以做内联,叫做Link-Time Code Generation or Whole Program Optimization或类似的东西(取决于您的工具链供应商)。启用此功能将
- 延长构建时间,并且
- 允许 link 使用者将函数内联到调用站点 跨源文件
因此,要内联函数,您有两种选择。要么将函数放入头文件,要么启用并依赖 link-time 优化为您内联它。
在您的特定情况下,要使用 __forceinline__
,您需要在头文件中定义 foo
。这需要 foo
的定义才能看到 func_a
和 func_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);
//...
}