【发布时间】:2020-08-06 19:07:30
【问题描述】:
如何正确定义根据 C99 标准取消引用不透明指针的内联函数?假设我在三个文件中组织了一个程序:
opaq.h:
typedef struct Opaq Opaq;
Opaq* opaq_init(void* ptr, int size);
void opaq_free(Opaq* o);
inline int opaq_size(Opaq* o);
opaq.c:
#include <stdlib.h>
#include "opaq.h"
struct Opaq {
void* ptr;
int size;
};
Opaq* opaq_init(void* ptr, int size)
{
Opaq* o = malloc(sizeof(*o));
o->ptr = ptr;
o->size = size;
return o;
}
void opaq_free(Opaq* o)
{
free(o);
}
int opaq_size(Opaq* o)
{
return o->size;
}
main.c:
#include <stdlib.h>
#include "opaq.h"
int main(void)
{
Opaq* o;
int size;
o = opaq_init(NULL, 3);
size = opaq_size(o);
opaq_free(o);
return 0;
}
我希望将opaq_size 内联到main.c。据我所知,这种内联是可能的,因为内联可以在链接期间发生。但是,尝试使用 GCC 编译它会给出以下警告:
$ gcc -Winline -o main main.c opaq.c
In file included from main.c:2:0:
opaq.h:5:12: warning: inline function ‘opaq_size’ declared but never defined
inline int opaq_size(Opaq* o);
在 opaq.h 中使用关键字 extern 会给出相同的警告。使用-fgnu89-inline 编译可以解决警告,但是反汇编main 会发现实际上没有发生内联。请注意,我无法在标题中定义函数(如static inline),因为结构定义超出范围。
【问题讨论】:
-
AFAIK,链接时优化内联完全独立于
inline关键字请求的编译时内联,而后者固有地要求函数的代码包含在(或包含into) 正在编译的翻译单元。 -
如果函数以任何方式取消引用该指针,则不能内联使用不透明指针的函数。如果可以,指针将不再是不透明的。
标签: c inline opaque-pointers