1

如果我使用 -fomit-frame-pointer 和 -mrtd 使用 GCC 编译,此 c 代码会因分段错误而崩溃。

我的代码在某种程度上是错误的吗?其他函数指针按预期工作,但不是在传递它的自由函数时?编译时收到警告,但我不明白为什么或应该做些什么来修复。(我通常不在 c 中编码,这个错误来自我使用的 3d 零件库)

我需要 rtd/stdcall 因为我在 Windows 上并且需要使用 ctypes 从 python 调用这个库,并且在使用 -O1 与 GCC 编译时默认包含 -fomit-frame-pointer。(GCC 版本是 4.6.1 from TDM/Mingw32) 感觉有点奇怪,默认优化选项会出问题?

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 *)'
4

2 回答 2

3

从 GCC 手册页-mrtd

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.

该警告有点奇怪,但我相信它只是试图告诉您您正在传递一个指向使用不兼容调用约定的函数的指针。我想freein libc 会是这样的功能;我很惊讶打电话calloc完全有效。(或者可能不是,您看到的是延迟失败!)

于 2012-06-05T18:01:19.333 回答
1

通过使用cdecl 属性正确声明函数指针,您应该能够解决问题,至少对于这个简单的示例。试试这个:

#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);
}
于 2012-06-05T21:16:55.290 回答