简体   繁体   English

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

[英]Contiguous memory guarantees with C++ function parameters

Appel [App02] very briefly mentions that C ( and presumably C++) provide guarantees regarding the locations of actual parameters in contiguous memory as opposed to registers when the address-of operator is applied to one of formal parameters within the function block. Appel [App02]非常简要地提到C( 并且可能是C ++)提供关于连续存储器中的实际参数的位置的保证,而不是当将地址运算符应用于功能块内的形式参数之一时的寄存器。

eg 例如

 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; } 

and an invocation such as... 和一个如...的调用

 foo(1,2,3,4); 

will produce the following output "1 2 3 4" 将产生以下输出“1 2 3 4”

My question is "How does this interact with calling conventions?" 我的问题是“这与调用约定如何相互作用?”

For example __fastcall on GCC will try place the first two arguments in registers and the remainder on the stack. 例如,GCC上的__fastcall将尝试将前两个参数放在寄存器中,其余的放在堆栈上。 The two requirements are at odds with each other, is there any way to formally reason about what will happen or is it subject to the capricious nature of implementation defined behaviour? 这两个要求是相互矛盾的,有没有办法正式推理将会发生什么,或者它是否受制于实施定义行为的反复无常的性质?

[App02] Modern Compiler Implementation in Java, Andrew w. [App02] Java中的现代编译器实现,Andrew w。 Appel, Chapter 6, Page 124 Appel,第6章,第124页

Update: I suppose that this question is answered. 更新:我想这个问题已得到解答。 I think I was wrong to base the whole question on contiguous memory allocation when what I was looking for (and what the reference speaks of) is the apparent mismatch between the need for parameters being in memory due the use of address-of as opposed to in registers due to calling conventions, maybe that is a question for another day. 当我正在寻找的内容(以及参考文献中提到的内容)是由于使用地址而导致参数在内存中的需求明显不匹配时, 我认为将整个问题建立在连续内存分配上是错误的。在寄存器中由于调用约定,这可能是另一天的问题。

Someone on the internet is wrong and sometimes that someone is me. 互联网上有人是错的,有时候有人就是我。

First of all your code doesn't always produce 1, 2, 3, 4. Just check this one: http://ideone.com/ohtt0 Correct code is at least like this : 首先,你的代码并不总是产生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++;
    }
}

So now let's try with fastcall , here : 现在让我们尝试使用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);
}

Result is messy: 1 -1216913420 134514560 134514524 结果很乱: 1 -1216913420 134514560 134514524

So I really doubt that something can be guaranteed here. 所以我真的怀疑这里可以保证一些东西。

The C++ standard has no concept of a calling convention. C ++标准没有调用约定的概念。 That's left for the compiler to deal with. 这是由编译器处理的。

In this case, if the standard requires that parameters be contiguous when the address-of operator is applied, there's a conflict between what the standard requires of your compiler and what you require of it. 在这种情况下,如果标准要求在应用address-of运算符时参数是连续的,那么标准对编译器的要求与您对它的要求之间存在冲突。

It's up to the compiler to decide what to do. 由编译器决定做什么。 I'd think most compilers would give your requirements priority over the standard's, however. 但是,我认为大多数编译器会将您的要求优先于标准。

There is nothing in the standard about calling conventions or how parameters are passed. 标准中没有关于调用约定或如何传递参数的内容。

It is true that if you take the address of one variable (or parameter) that one has to be stored in memory. 确实,如果你获取一个必须存储在内存中的变量(或参数)的地址。 It doesn't say that the value cannot be passed in a register and then stored to memory when its address is taken. 它没有说该值不能在寄存器中传递,然后在其地址被存储时存储到存储器中。

It definitely doesn't affect other variables, who's addresses are not taken. 它肯定不会影响其他变量,不会采用谁的地址。

Your basic assumption is flawed. 你的基本假设是有缺陷的。 On my machine, foo(1,2,3,4) using your code prints out: 在我的机器上, foo(1,2,3,4)使用你的代码打印出来:

1 -680135568 32767 4196336 1 -680135568 32767 4196336

Using g++ (Ubuntu 4.4.3-4ubuntu5) 4.4.3 on 64-bit x86. 在64位x86上使用g++ (Ubuntu 4.4.3-4ubuntu5) 4.4.3

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM