可以通过参数传递结构吗?它和卡比兼容吗?
**[编辑]
基本上,我希望有一个C++ POD,它包含两个成员(结构将是一个胖指针,一个指针和一个整数),并能够在调用指令中将此结构作为函数参数传递(即使在调用C代码时)。我现在没有使用胖指针(指针和整数分别在不同的函数参数中),我想在开始一个相当大的重构之前知道它是否可能!
8fsztsew1#
你能做到的。您可以通过将C代码复制并粘贴到LLVM的在线演示http://llvm.org/demo/index.cgi中来了解示例C的LLVM代码。If you copy and paste the code at codepad.org in, you'll see that LLVM generates the following for myFunction:
define void @_Z10myFunction10MyStruct_t(i8* %myStructAsParam.coerce0, i32 %myStructAsParam.coerce1) nounwind uwtable { %1 = tail call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([23 x i8]* @.str, i64 0, i64 0), i8* %myStructAsParam.coerce0, i32 %myStructAsParam.coerce1) ret void }
当然,如果你看一下调用,你会注意到没有复制,这取决于调用函数,如果我们写一个小的C函数:
void myCallingFunction(MyStruct_t *foobar) { myFunction(*foobar); }
我们可以看到,为myCallingFunction生成的LLVM位代码为:
define void @_Z17myCallingFunctionP10MyStruct_t(%struct.MyStruct_t* nocapture %foobar) nounwind uwtable { %foobar.0 = getelementptr inbounds %struct.MyStruct_t* %foobar, i64 0, i32 0 %tmp = load i8** %foobar.0, align 8 %foobar.1 = getelementptr inbounds %struct.MyStruct_t* %foobar, i64 0, i32 1 %tmp1 = load i32* %foobar.1, align 8 %1 = tail call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([23 x i8]* @.str, i64 0, i64 0), i8* %tmp, i32 %tmp1) nounwind ret void }
调用函数复制该结构,然后传入副本的地址。
vzgqcmou2#
这在今天的LLVM中是不可能的,因为它与C语言的ABI和调用约定是可靠兼容的。使用LLVM的聚合类型是可以做到这一点的,但这并不能提供任何稳定的或特定的ABI。这些也不是LLVM特性的最佳支持,特别是在复杂的情况下或在函数边界上。但是您描述的简单的POD用例应该可以工作。有关C语言兼容性挑战的更多详细信息,请参见我对相关SO问题的回答:https://stackoverflow.com/a/75002581/552038
knsnq2tg3#
当然可以。举个例子:
struct MyStruct_t { char *charPointer; int number; }; void myFunction(MyStruct_t myStructAsParam) { printf("String: %s, Number: %i", myStructAsParam.charPointer, myStructAsParam.number); // Your stuff here. }
3条答案
按热度按时间8fsztsew1#
你能做到的。
您可以通过将C代码复制并粘贴到LLVM的在线演示http://llvm.org/demo/index.cgi中来了解示例C的LLVM代码。
If you copy and paste the code at codepad.org in, you'll see that LLVM generates the following for myFunction:
当然,如果你看一下调用,你会注意到没有复制,这取决于调用函数,如果我们写一个小的C函数:
我们可以看到,为myCallingFunction生成的LLVM位代码为:
调用函数复制该结构,然后传入副本的地址。
vzgqcmou2#
这在今天的LLVM中是不可能的,因为它与C语言的ABI和调用约定是可靠兼容的。
使用LLVM的聚合类型是可以做到这一点的,但这并不能提供任何稳定的或特定的ABI。这些也不是LLVM特性的最佳支持,特别是在复杂的情况下或在函数边界上。但是您描述的简单的POD用例应该可以工作。
有关C语言兼容性挑战的更多详细信息,请参见我对相关SO问题的回答:https://stackoverflow.com/a/75002581/552038
knsnq2tg3#
当然可以。举个例子: