使用C++函数参数保证连续内存

Dun*_*ter 9 c++ memory-management function calling-convention

Appel [App02]非常简要地提到C(并且可能是C++)提供关于连续存储器中的实际参数的位置的保证,而不是当将地址运算符应用于功能块内的形式参数之一时的寄存器.

例如

void foo(int a, int b, int c, int d)
{
    int* p = &a;
    for(int k = 0; k < 4; k++)
    {
       std::cout << *p << " ";
       p++;
    }
    std::cout << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

和一个如...的调用

foo(1,2,3,4);
Run Code Online (Sandbox Code Playgroud)

将产生以下输出"1 2 3 4"

我的问题是"这与调用约定如何相互作用?"

例如,GCC上的__fastcall将尝试将前两个参数放在寄存器中,其余的放在堆栈上.这两个要求是相互矛盾的,有没有办法正式推理将会发生什么,或者它是否受制于实施定义行为的反复无常的性质?

[App02] Java中的现代编译器实现,Andrew w.Appel,第6章,第124页

更新:我想这个问题已得到解答.当我正在寻找的内容(以及参考文献中提到的内容)是由于使用地址而导致参数在内存中的需求明显不匹配时,我认为将整个问题建立在连续内存分配上是错误的.在寄存器中由于调用约定,这可能是另一天的问题.

互联网上有人是错的,有时候有人就是我.

And*_*rey 3

首先,你的代码并不总是产生 1, 2, 3, 4。只需检查这个: http: //ideone.com/ohtt0 正确的代码至少是这样

void foo(int a, int b, int c, int d)
{
    int* p = &a;
    for (int i = 0; i < 4; i++)
    {
        std::cout << *p;
        p++;
    }
}
Run Code Online (Sandbox Code Playgroud)

现在让我们尝试fastcall一下:

void __attribute__((fastcall)) foo(int a, int b, int c, int d)
{
    int* p = &a;
    for (int i = 0; i < 4; i++)
    {
        std::cout << *p << " ";
        p++;
    }
}

int main()
{
        foo(1,2,3,4);
}
Run Code Online (Sandbox Code Playgroud)

结果很乱:1 -1216913420 134514560 134514524

所以我真的很怀疑这里能保证什么。