我有一个函数(我们称之为 void foo(void) {}
),我希望将其内联。但我在 .cpp 文件中定义了它。
我无法将该函数移动到 header ,因为它正在使用 .cpp 中的其他函数。
编辑:
下面的代码就像真实的代码一样,没有使用 C++ 功能。我可以明确地补充:
#ifdef __cplusplus
extern "C"
#endif
如果我想将下面的代码转换为 c99,我只需要更改我的项目属性(或 makefile,如果您愿意)不是代码。我也在询问c++,因为它可以解决我的问题,而c99不能。
因此我的问题中的 C 和 C++ 标签是合理的。代码是可移植的
请参阅:When to use extern "C" in 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()
不内联是可扩展的。 - 我厌倦了只有 header 的库。
我尝试过:
文件.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
我不明白为什么会收到此警告。
有没有办法:
- 将
foo()
的定义保留在我的 .cpp 文件中吗?但仍然使其内联 - 将
foo()
移至file.h
,将func_a()
和func_b()
保留在其中file.cpp
,但使func_a()
和func_b()
符号对foo()
“可见” (!且仅限于foo()
!)来自file.cpp
- 还有其他解决方法吗?
抱歉,我仍在学习 cpp,我不知道我的问题是否清楚,或者是否有可能从 .cpp 文件中内联函数。
最佳答案
在 C++ 中,inline
关键字的含义是:
- 函数体必须出现在使用该函数的每个源文件中。
- 所有源文件中的函数“主体”必须逐个 token 和逐个实体相同。
- 编译器和链接器必须确保它们适合具有这些“多个主体”的函数
这就是它的全部作用。实际上,这意味着它可以并强制您将函数体放入头文件中。
关键字本身与函数内联无关。只是如果编译器希望能够内联函数体,它必须在编译调用代码时能够访问它;换句话说,函数的主体必须位于同一源文件中或位于该源文件包含的头文件中。
如果您想让编译器在所有调用站点中内联该函数,并且这些调用站点发生在多个源文件中,则必须将该函数放入头文件中(并且将其标记为内联
)。
另一方面,链接器也可以进行内联,称为链接时代码生成或整个程序优化或类似的东西(取决于您的工具链供应商)。启用此功能将
- 延长构建时间,并且
- 允许链接器将函数内联到跨源文件的调用站点
因此,要内联该函数,您有两种选择。要么将该函数放入头文件中,要么启用并依赖链接时优化来为您内联它。
在您的特定情况下,要使用__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);
//...
}
关于c++ - extern 内联函数被引用但未定义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40766329/