1

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?

5
  • 1
    "An array name is a pointer" is not an accurate statement, read Is an array name a pointer? Commented Aug 20, 2020 at 10:35
  • 1
    structs 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. Commented Aug 20, 2020 at 10:36
  • 3
    You 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. Commented Aug 20, 2020 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. Commented Aug 20, 2020 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. Commented Aug 20, 2020 at 13:42

3 Answers 3

2

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 designators
...
3     Except when it is the operand of the sizeof 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 has register storage class, the behavior is undefined.
C 2011 Online Draft

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 the 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.
ibid.

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.


  1. If you're really interested, you can read Ritchie's own account of developing C in this article.
Sign up to request clarification or add additional context in comments.

Comments

1

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.

Comments

0

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.

1 Comment

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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.