简体   繁体   中英

Why Struct name is not a pointer in C?

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?

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.

Arrays are weird. They do not behave like other types.

C was derived from an earlier language named B 1 , 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 .

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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