如果我使用-fomit-frame-pointer和-mrtd使用GCC进行编译,则此c代码会因分段错误而崩溃。
我的代码在某种程度上是错误的吗?其他函数指针按预期工作,但是当它的自由函数被传递时却没有?我在编译时收到警告,但我不明白为什么或应该做些什么来修复。 (我通常不用c编码,这个错误来自我使用的3d零件库)
我需要rtd / stdcall,因为我在Windows上需要使用ctypes从python调用此库,并且在使用-O1与GCC进行编译时默认包含-fomit-frame-pointer。 (GCC版本是TDM / Mingw32的4.6.1)默认优化选项会引起麻烦有点奇怪吗?
C代码:
#include <stdlib.h>
// void free ( void * ptr );
void test(void* o, void (*freeFunc)(void*)) {
freeFunc(o);
}
int main() {
int *p = (int *)calloc(1, sizeof(int));
test(p, free);
}
编译:
gcc -fomit-frame-pointer -mrtd -c fx.c
gcc -fomit-frame-pointer -mrtd fx.o -o fx.exe
编译警告:
fx.c: In function 'main':
fx.c:11:5: warning: passing argument 2 of 'test' from incompatible pointer type[enabled by default]
fx.c:5:6: note: expected 'void (*)(void *)' but argument is of type 'void (*)(void *)'
答案 0 :(得分:3)
来自-mrtd
的GCC手册页:
Warning: this calling convention is incompatible with the one
normally used on Unix, so you cannot use it if you need to call
libraries compiled with the Unix compiler.
警告有点奇怪,但我相信它只是试图告诉你,你正在向一个使用不兼容调用约定的函数传递指针。我想libc中的free
就是这样一个函数;我很惊讶调用calloc
可以工作。 (或许它不是,你所看到的是延迟失败!)
答案 1 :(得分:1)
至少在这个简单的例子中,您应该可以通过使用cdecl attribute正确声明函数指针来解决问题。试试这个:
#include <stdlib.h>
void test(void* o, void (__attribute__((cdecl))*freeFunc)(void*)) {
freeFunc(o);
}
int main() {
int *p = (int *)calloc(1, sizeof(int));
test(p, free);
}