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);
Some Windows structures are variable-sized, beginning with a fixed header, followed by a variable-sized array. When these structures are declared, they often declare an array of size 1 where the variable-sized array should be.
The pointer ptr, and all pointers, are 8 bytes, because they hold addresses, which are 8 bytes, or 64 bits. Assigning any address to an array variable is not allowed.
foo=sizeof(para)/sizeof(para[0]);
length -1 means, specifically the -1 part. When using a for loop over an array we have something like this: for (i = 0; i < array. length; i++) {...}
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.
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:
// 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; 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:
Therefore, it is safe to assume that these two methods are identical.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With