我正在重写我的一个小C数学库,它最终会成为用户的静态库,并希望从我的矢量数学界面的内联中受益.
我有以下内容:
[mymath.h]
...
...
extern float clampf( float v, float min, float max );
...
...
Run Code Online (Sandbox Code Playgroud)
[mymath.c]
inline float clampf( float v, float min, float max )
{
if( v < min ) v = min;
if( v > max ) v = max;
return v;
}
Run Code Online (Sandbox Code Playgroud)
由于我的库是静态的,我只是要向用户提供.h
(和.lib
),clampf
在编译时是否会在程序中内联函数?
我做了正确的事情,但在声明函数extern
在.h
中和内联.c
?
Die*_*Epp 17
你几乎是正确的.你实际上倒退了; 对于内联函数,您必须将inline
定义放在头文件中,并将extern
声明放在C文件中.
// mymath.h
inline float clampf( float v, float min, float max )
{
if( v < min ) v = min;
if( v > max ) v = max;
return v;
}
// mymath.c
#include "mymath.h"
extern float clampf( float v, float min, float max );
Run Code Online (Sandbox Code Playgroud)
您必须将定义(完整正文)放在头文件中,这将允许任何包含头文件的文件能够在编译器选择时使用内联定义.
您必须将extern
声明(原型)放在源文件中,以告诉编译器在库中发出该函数的外部版本.这为您的库提供了非内联版本的一个位置,因此编译器可以在内联函数或使用通用版本之间进行选择.
请注意,这可能不适用于MSVC编译器,MSVC编译器通常对C的支持非常差(并且几乎没有支持C99).对于GCC,您必须为旧版本启用C99支持.Modern C编译器默认支持此语法.
替代方案:
您可以更改标题以获得static inline
版本,
// mymath.h
static inline float clampf(float v, float min, float max)
{
...
}
Run Code Online (Sandbox Code Playgroud)
但是,这不提供函数的非内联版本,因此可能会强制编译器为每个转换单元创建此函数的副本.
笔记:
C99内联规则并不完全直观.文章" C中的内联函数 "(镜像)详细描述了它们.特别是,请跳到底部并查看"使用内联函数的策略".我更喜欢方法#3,因为GCC已经默认为C99方法一段时间了.
从技术上讲,您永远不需要设置extern
函数声明(或定义),因为extern
它是默认值.我把它放在那里强调.
您应该static inline
在.h文件中定义您的函数:
static inline float clampf( float v, float min, float max )
{
if( v < min ) v = min;
if( v > max ) v = max;
return v;
}
Run Code Online (Sandbox Code Playgroud)
.c文件中必须不存在该函数.
编译器可能决定不内联函数,但使其成为正确的函数调用.因此,每个生成的.o文件都可能包含该函数的副本.