编译的 gcc 和 tcc 结构的兼容性

phi*_*sky 4 c c++ gcc struct tcc

我正在尝试从 C++ 运行 libtcc 以使用 C 作为运行时脚本语言。运行时编译的代码必须能够运行外部代码中的函数。当传递整数时,这工作得很好,但是当将结构从 tcc 代码传递到 gcc 代码时,会发生奇怪的事情。

最小运行示例:

#include <libtcc.h>
#include <stdio.h>
struct Vec {
    int x;
};
void tmp(struct Vec test) {
    printf("got %x\n",test.x);
}
int main() {
    TCCState* tcc; tcc = tcc_new();
    tcc_set_output_type(tcc, TCC_OUTPUT_MEMORY);
    tcc_add_symbol(tcc, "tmp", (void*)&tmp);
    tcc_compile_string(tcc, "\
        struct Vec {int x;};\
        void tmp(struct Vec test);\
        void fun() {\
            struct Vec x = {0};\
            tmp(x);\
        }");
    tcc_relocate(tcc, TCC_RELOCATE_AUTO);
    void (*fun)(void) = (void(*)())tcc_get_symbol(tcc, "fun");
    fun();
}
Run Code Online (Sandbox Code Playgroud)

运行:

gcc -ltcc -ldl test.c && ./a.out
> got 23b472b0
tcc -ltcc -ldl test.c && ./a.out
> got 0
Run Code Online (Sandbox Code Playgroud)

为什么gcc编译版本没有打印出预期的0?当我只将long longs 而不是 int 放入结构中时,它就可以工作。输出任何其他数据类型和随机内容。

起初我以为这是因为对齐或其他原因,但当结构中仅使用单个变量时也会发生这种情况。

我正在使用 Linux 3.16 x86_64 和 tcc 0.9.26

Cha*_*ohr 5

问题似乎集中在 C 和 C++ 将整个“struct Vec test”理解为参数的方式上。在 TCC 中,它被视为/假定为指针。在 C++ 中,看起来必须更清楚地声明它是一个指针。

#include libtcc.h
#include stdio.h
struct Vec {
    int x;
};
void tmp(struct Vec * test) {
    printf("got %x\n",test->x);
}
int main() {
    TCCState* tcc; tcc = tcc_new();
    tcc_set_output_type(tcc, TCC_OUTPUT_MEMORY);
    tcc_add_symbol(tcc, "tmp", (void*)&tmp);
    tcc_compile_string(tcc, "\
        struct Vec {int x;};\
        void tmp(struct Vec test);\
        void fun() {\
            struct Vec x = {5};\
            tmp(x);\
        }");
    tcc_relocate(tcc, TCC_RELOCATE_AUTO);
    void (*fun)(void) = (void(*)())tcc_get_symbol(tcc, "fun");
    fun();
}
Run Code Online (Sandbox Code Playgroud)

输出显示为:

got 5
Run Code Online (Sandbox Code Playgroud)

  • @phiresky:结构按值传递。(如果编译器使用指针实现按值传递,那就没问题,只要语义相同。)如果带有参数“struct Vec test”的函数修改“Test”的成员,则该更改不得影响调用者——对 tcc 版本 0.9.25 的快速实验表明 tcc 做到了这一点。(我不知道这些“TCCState”内容是关于什么的。) (2认同)