2

Pointer always stores a integer value i.e address so why do we need to declare them with different data type.

Like

int a=3,*p=&a;
char c=r,*cha=&r;

why can't we do like

int *c;
char r=a;
c=&r;
Dante777
  • 21
  • 2

5 Answers5

6

Essentially it's because

  1. Pointer arithmetic would not work if the pointer types were not explicit.

  2. The pointer to member operator would not work for struct pointer types.

  3. The alignment requirements for types can differ. It might be possible to store a char at a location where it's not possible to store an int.

  4. The sizes of pointers are not guaranteed to be the same by the C standard: i.e. sizeof(int*) is not necessarily the same as sizeof(char*). This allows C to be used on exotic architectures.

Bathsheba
  • 231,907
  • 34
  • 361
  • 483
  • 3
    Also struct pointers need to know the members they can point to. – Barmar Mar 29 '17 at 07:27
  • @Barmar: Pinched that. That reason, along with the pointer arithmetic one are probably the two most important. – Bathsheba Mar 29 '17 at 07:28
  • 1. is not completely right as stated. Untyped pointer could assume object size of 1 as do compiler extensions that allow pointer arithmetic with `void *` like gcc. So untyped pointer do not make arithmetic impossible, they only do them unwieldy as one would have to include the implicit `sizeof *p` explicit. – Patrick Schlüter Mar 29 '17 at 08:27
  • 1
    2. is also not completely true when one knows how it was in the beginning of the C compilers at AT&T. The field names of a struct were in the global name space (now they are in the struct's namespace) and they represented an offset from the beginning of the structure. The field name was in fact nothing more than a constant (what nowadays would be `offsetof(struct x, field)`). `a->b` is lowerd to `*(a+b)` anyways, so there is nothing preventing pointer arithmetic here. – Patrick Schlüter Mar 29 '17 at 08:33
  • 3. This one is solid. – Patrick Schlüter Mar 29 '17 at 08:36
  • 4. True. Harvard architectures with separate memory spaces and some mainframes have really strange pointer rules. – Patrick Schlüter Mar 29 '17 at 08:39
  • Regarding 4, the C standard states that any pointer type may be converted to another pointer type and back again, without losing information. In practice this means that they will have the same size, or otherwise this C standard requirement will be very hard to fulfil. – Lundin Mar 29 '17 at 08:58
  • 1
    @Lundin Detail: The round tripping of pointers does not apply to conversion to/from pointers between pointers to objects and pointers to functions. Further the round tripping of object pointers is through `void*`. `int*` to `char *` to `int*` need not work - it can lose information. C11 6.3.2.3 1 – chux - Reinstate Monica Mar 29 '17 at 14:43
1

To pass to the "user" of the pointer information about what kind of data the pointer points to. Basing on that it will/may depend how the pointed data will be interpreted and handled. Any time you can use a pointer to void, in this case that information is not available. Then, the user of that pointer should know from other sources what is pointed and how to work with it.

dmi
  • 1,424
  • 1
  • 9
  • 9
  • "Any time you can use a pointer to void" --> A pointer to a function may not fit in a `void*`. `void*` is not a universal pointer type for all, but is universal for pointer to objects. – chux - Reinstate Monica Mar 29 '17 at 14:49
  • Correct, I have left a bit freedom to interpret the words )) – dmi Mar 30 '17 at 05:07
1

Batcheba has already 4 good reasons. Let me give some less important ones:

  • function pointer and data pointer are not even compatible according to the standard (Harvard architecture with separate code and data address spaces, memory models of segmented architectures, etc.).

  • the optimizer can exploit the fact that pointer on different types generally do not overlap and can elide a lot of memory loads that way (https://en.wikipedia.org/wiki/Pointer_aliasing)

Patrick Schlüter
  • 11,394
  • 1
  • 43
  • 48
  • Do feel free to copy the 4 reasons from my answer, order to end up with a comprehensive answer. – Bathsheba Mar 29 '17 at 08:35
  • No, it's ok that way. I wouldn't want to free ride on your answer which is good. I commented a little on them to because I'm an annoying nitpicker :-) but it's ok as it is. – Patrick Schlüter Mar 29 '17 at 08:44
  • 1
    But you raise some very good points in my answer comments. And I'll be sure to upvote a comprehensive answer from you. – Bathsheba Mar 29 '17 at 08:45
0
int *c;
char r=a;
c=&a;

In your declaration a is just a character not a variable. A pointer when defined can only store the address of a specific type of variable. If you declare c as int *c, the pointer can only point on variables of type integer.

GGamba
  • 13,140
  • 3
  • 38
  • 47
-1

Of course you can assign an address value to any type pointers.

int d;
char* cp = (char*)&d;     // OK
float* fp = (float*)&d;   // OK

But when you get content from the address, you MUST know the type. Otherwise the compiler will not know how to interpret it.

Holsety
  • 103
  • 7
  • `float* fp = (float*)&d;` is not OK, it is a strict aliasing violation and undefined behavior if you attempt to use the pointed-at data. [What is the strict aliasing rule?](http://stackoverflow.com/questions/98650/what-is-the-strict-aliasing-rule). – Lundin Mar 29 '17 at 08:53
  • @Lundin I don't know about strict aliasing violation. Which compiler has this action? – Holsety Mar 29 '17 at 09:00
  • All standard-compliant compilers have it. Although only gcc is known to actively abuse strict aliasing for optimization purposes. For example, code like `int a = 123; *(float*)&a = 0.0f; if(a != 123){ printf("%d", a); } else { puts("a not changed"); }` might print "a not changed". – Lundin Mar 29 '17 at 09:15
  • A pointer to `int` and one to `float` may have different alignment requirements. `float* fp = (float*)&d;` is not OK. – chux - Reinstate Monica Mar 29 '17 at 14:47