简体   繁体   English

大小为1的数组与指向struct的指针

[英]Array of size 1 vs. pointer to struct

Let's say I have a function which takes an array of structs, defined like so: 假设我有一个函数,它接受一个结构数组,定义如下:

void Foo(struct MyStruct *s, int count) {
    for (int i = 0; i < count; ++i) {
        // Do something with s[i]
    }
}

Are these following two snippets guaranteed to behave the same way? 以下两个片段是否保证以相同的方式运行?

struct MyStruct s;
s.x = 0;
s.y = 0;
Foo(&s, 1);

vs.

struct MyStruct s[1]; // stack-allocated array of size 1
s[0].x = 0;
s[0].y = 0;
Foo(s, 1);

The answer is yes, they are effectively the same. 答案是肯定的,它们实际上是一样的。 First, arrays are passed as pointer to its first element, when used in function arguments. 首先,当在函数参数中使用时,数组作为指向其第一个元素的指针传递。 Actually, all objects in C can be treated as a array of one element of that type in terms of storage. 实际上,C中的所有对象都可以在存储方面被视为该类型的一个元素的数组。

They are identical; 它们完全相同; proof - I compiled and saved the assembly code generated by both MSVC 2015 and GCC 4.9.3 for these two code samples: 证明 - 我为这两个代码示例编译并保存了MSVC 2015和GCC 4.9.3生成的汇编代码:

// Case 1: Pass by reference to single struct
typedef struct _mystruct
{
    int x;
    int y;
} mystruct;

void foo(mystruct *s, int count)
{
    int i;
    for(i = 0; i < count; i++)
    {
        (*(s + i)).x = 5; 
        (*(s + i)).y = 7;
    }
}

int main()
{
    mystruct ps;

    //mystruct as[1];


    foo(&ps, 1);
    //foo(as, 1);
    return 0;
}

I note that the operations in foo are random and not really relevant to the test; 我注意到foo中的操作是随机的,与测试无关; they are just to prevent the compiler from optimizing out the method. 它们只是为了防止编译器优化方法。

// Case 2: 1-length array
typedef struct _mystruct
{
    int x;
    int y;
} mystruct;

void foo(mystruct *s, int count)
{
    int i;
    for(i = 0; i < count; i++)
    {
        (*(s + i)).x = 5; 
        (*(s + i)).y = 7;
    }
}

int main()
{
    //mystruct ps;

    mystruct as[1];


    //foo(&ps, 1);
    foo(as, 1);
    return 0;
}

In the generated assembly files, on GCC they are exactly identical, and in MSVC, literally the only differences are: 在生成的汇编文件中,在GCC上它们完全相同,而在MSVC中,字面上唯一的区别是:

  1. The variable names in the comments (s vs as) 注释中的变量名称(s vs as)
  2. The line numbers referenced (since different ones are uncommented in each version). 引用的行号(因为在每个版本中取消注释不同的行号)。

Therefore, it is safe to assume that these two methods are identical. 因此,可以安全地假设这两种方法是相同的。

Yes. 是。 Both options are stack-allocated and create exactly one 'instance' of struct MyStruct . 这两个选项都是堆栈分配的,并且只创建了一个struct MyStruct “实例”。 Your compiler is expected to output the same machine code for both options. 您的编译器应为两个选项输出相同的机器代码。 See this link (C) and this link (C++) for more details. 有关详细信息,请参阅此链接 (C)和此链接 (C ++)。

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

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