An array name is a pointer and a function name is also a pointer but a Struct name is not a pointer. I am trying to understand if there is some logical reasoning behind this difference or it is just a random syntax of C language?
-
1*"An array name is a pointer"* is not an accurate statement, read [Is an array name a pointer?](https://stackoverflow.com/q/1641957/6865932) – anastaciu Aug 20 '20 at 10:35
-
1structs behave like base types (think `int` `long` `char`) this allows to pass structs to functions by-value or by pointer (both) instead of by-pointer-only. – NeonMan Aug 20 '20 at 10:36
-
3You mean "decays" into a pointer when passed/assigned. Consider `struct name` a type and `struct name *` a pointer to type and it will make more sense. – David Ranieri Aug 20 '20 at 10:37
-
It's because there's not much else you can do with an array or a function, than get a pointer to it. But there are other things you can do with structs. – user253751 Aug 20 '20 at 12:46
-
An `int`'s name does not represent a pointer and does not decay to one. Nor a `double`'s, a `float`'s, a `char`'s, *etc*.. And a pointer's name represents the corresponding value directly, not as a pointer to another pointer. This is the standard pattern for identifiers of objects, which structures and unions also follow. Arrays are the oddball exception, and function identifiers are a rather different beast. – John Bollinger Aug 20 '20 at 13:42
3 Answers
Arrays are weird. They do not behave like other types.
C was derived from an earlier language named B1, which maintained a separate pointer to the first element of an array. Given the declaration
auto a[10];
you’d get something like the following in memory:
+–––+
a: | | ––+
+–––+ |
... |
+–––––+
|
v
+–––+
| | a[0]
+–––+
| | a[1]
+–––+
...
+–––+
| | a[9]
+–––+
The array subscript operation a[i]
was defined as *(a+i)
- given the starting address stored in a
, offset i
elements (not bytes) from that address and dereference the result.
When designing C, Ritchie wanted to keep B’s array semantics, but he didn’t want to keep the separate pointer to the first element, so he got rid of it - instead, he created the rule which eventually got standardized as follows:
6.3.2.1 Lvalues, arrays, and function designatorsC 2011 Online Draft
...
3 Except when it is the operand of thesizeof
operator, the_Alignof
operator, or the unary&
operator, or is a string literal used to initialize an array, an expression that has type ‘‘array of type’’ is converted to an expression with type ‘‘pointer to type’’ that points to the initial element of the array object and is not an lvalue. If the array object hasregister
storage class, the behavior is undefined.
When you declare an array in C like
int a[10];
you get this in memory:
+---+
a: | | a[0]
+---+
| | a[1]
+---+
...
+---+
| | a[9]
+---+
No space for a separate pointer object has been allocated. The subscript operation a[i]
is still defined as *(a + i)
, it's just in this case the expression a
is converted from array type to pointer type as part of the computation.
This is important - the array name a
is not a pointer. Instead, the expression a
is converted from array type to pointer type as necessary.
There's a similar rule for functions:
4 A function designator is an expression that has function type. Except when it is the operand of theibid.sizeof
operator, the_Alignof
operator,65) or the unary&
operator, a function designator with type ‘‘function returning type’’ is converted to an expression that has type ‘‘pointer to function returning type’’.
65) Because this conversion does not occur, the operand of the sizeof or _Alignof operator remains a function designator and violates the constraints in 6.5.3.4.
Struct types don't work like arrays - members aren't accessed based on a numerical offset from a base address. There's a completely different mechanism at work, so a struct foo
expression doesn't "decay" to a pointer type the same way as an array expression or a function designator.
- If you're really interested, you can read Ritchie's own account of developing C in this article.

- 119,563
- 19
- 122
- 198
I think that the main reason is that objects of structure (and union) types opposite to arrays have the assignment operator.
So for example you may write
struct A a1;
struct A a2;
a1 = a2;
If an object of a structure type would decay to a pointer then this assignment would not have a sense.

- 301,070
- 26
- 186
- 335
There is one and only one instance of array or function, so we can point to them. However, there can be many instances of the structure, so we cannot point to the structure, but we can point to the structure instances.

- 120
- 5
-
I think you are missing the point. Inasmuch as they draw a comparison with arrays, I take the OP to be talking about *identifiers of objects* of structure type, not about type names of structure types. – John Bollinger Aug 20 '20 at 13:31