gpt4 book ai didi

c++ - 使用结构调用需要独立参数的 C++ 函数是否安全?

转载 作者:搜寻专家 更新时间:2023-10-31 00:58:41 27 4
gpt4 key购买 nike

基本上,执行以下操作是否安全:

我们有一个接受任意数量参数的简单函数调用:

void simpleCall(int x, int y, int z, int a, int l, int p, int k)
{
printf("%i %i %i %i %i %i %i\n", x, y, z, a, l, p, k);
}

我们创建一个映射到参数的结构:

struct simpleArgs
{
int x;
int y;
int z;
int a;
int l;
int p;
int k;
};

我们用要传递的参数初始化结构,转换函数以便编译,并传递结构代替所有参数:

int main()
{
simpleArgs a;
a.x = 1;
a.y = 2;
a.z = 3;
a.a = 4;
a.l = 5;
a.p = 6;
a.k = 7;

((void(*)(simpleArgs))simpleCall)(a);

return 0;
}

程序打印:

1 2 3 4 5 6 7

这个特殊的例子没有任何意义(我们可以很容易地正常调用函数)但是它是为了说明这个概念而写的。因为结构是按值传递的,所以这是否与按值传递每个参数相同?标准调用将参数作为一个组放在堆栈上,这应该与我们在这里看到的相同吗?在什么情况下通过寄存器传递参数?

看起来这是可行的,这可能是 cdecl x86、我测试过的编译器和我选择的参数类型的侥幸。这看起来非常脆弱,以至于如果您选择了一些不是 16 位对齐的变量类型并且没有显式修改结构以使其对齐,则可能会出现 SIGSEV。

最佳答案

传递单个参数和将一个参数作为 struct 传递通常被当作不同的事情来处理。例如,没有说 struct 只是按原样传递:

 struct X x;
... fill in x...
func(x);

相反,有时它会变成:

 struct X x;
... fill in x...
struct X tmp = x;
func(&tmp);

(换句话说,参数的拷贝是在调用点创建的,然后作为地址传递,而不是在函数内部或在实际调用期间传递 - 巧合的是,这就是我的 Pascal 编译器执行此类传递的方式) .

有时结构的大小将决定整个结构是加载到寄存器中还是作为内存中的拷贝传递(其中各个参数将是寄存器和内存的混合)。参数的顺序可能与结构存储在内存中的顺序不同。

绝对没有一件事表明这应该有效。它可能会偶然发生。如果您决定更改编译器优化级别或针对不同的处理器类型进行编译,它也可能会中断。

关于c++ - 使用结构调用需要独立参数的 C++ 函数是否安全?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35031812/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com