Reputation: 27633
Is the return value of this function well defined by the C standard?
int foo()
{
char buff[128];
// This is the important line:
if ((void*)buff == (void*)(&buff))
return 1;
else
return 0;
}
What is the result of foo
? On gcc
and clang
, it will always be 1
, but I do not think that this is guaranteed by the standard.
Upvotes: 2
Views: 194
Reputation: 239051
It will always return 1.
An array is a contiguously allocated non-empty set of objects with the element type - arrays are not allowed to have padding before or between elements. It follows that a pointer to an array points at the same location as a pointer to the first element, although it has a different type.
&buff
is the address of the variable buff
. The variable buff
in this case is an array, so &buff
is the address of an array - and just like the address of a struct
variable is the same location as the address of its first member (although a different type), the address of an array variable is the same location as the address of its first member.
§6.5.9 tells us:
6 Two pointers compare equal if and only if both are null pointers, both are pointers to the same object (including a pointer to an object and a subobject at its beginning)...
In this case the "pointer to an object" is the pointer to the array, and the "pointer to the subobject at its beginning" is the pointer to the first element of the array.
In other words, it returns 1 for much the same reason that this code does:
int foo()
{
struct { int a; int b; } s;
return (void*)&s == (void*)&s.a;
}
Upvotes: 3
Reputation: 44250
Yes: a pointer to an array decays into a pointer to the first element; so &buff[0] == &buff
. In your case there is another thing: when used as a function argument (such as memcpy (buff, ...) ) an array name decays into a pointer.
For sizeof buff
, the buff does not decay into a pointer. (hint: use short, or long long to test that, or a platform where sizeof (void*) != sizeof (int). )
Upvotes: 2
Reputation: 18492
Are they [
buff
and&buff
] guaranteed to have the same value or is that something that just happens with gcc and clang? I ask because I don't think &buff is "the address of the start of the array," but the address of the variable buff.
They are guaranteed to be the same value. In C arrays can be considered "special" in the sense that they're not pointers and the only time they're treated as such is when they're passed to a function and they decay to pointers.
For that reason:
buff == &buff && buff == &buff[0]
However buff
and &buff
are of two different types, where &buff
is a pointer to the array (they still refer to the same spot!). You can use sizeof
on the two to see this difference for yourself.
That is not the same for a pointer, which as you say will return the address of that actual pointer variable. An array also isn't a pointer to itself since in order for a pointer to point to itself, the address of that pointer would need to be stored in that pointer variable.
An array name is simply a label used by the compiler that corresponds to a contiguous block of memory. It has special properties, the above being one of them.
Upvotes: 6