0

I am not used to pointers because I started learning Pascal in high school and now I am upgrading myself to C. My request would be to explain me what should I think when I see something like this [*(char*)p1]. Don't be shy writing me quite a few lines :)

Thank you.

P.S. p1 is a const void *. To be more accurate.

Shafik Yaghmour
  • 154,301
  • 39
  • 440
  • 740
MaXiMkA
  • 449
  • 3
  • 6
  • 14
  • I'd say, cast `p1` to `char*` and dereference it (grab the value at that address). The value is being used as an array index `[ ]`. – bblincoe Jan 10 '14 at 13:30
  • Before `[` in `[*(char*)p1]` there should be some array name. `[*(char*)p1]` alone will be a compiler error as @[Damon](http://stackoverflow.com/a/21045657/1673391) also mentioned. – Grijesh Chauhan Jan 10 '14 at 13:32
  • My answer to this question might help you understand this. http://stackoverflow.com/questions/21034253/explain-the-pointers-to-pointers-issue/21034375#21034375 – Eric Lippert Jan 10 '14 at 19:08

4 Answers4

3

Assuming that [*(char*)p1] is an array designator, (char*) is used to cast p1 to make p1 char * type. Then * is used to dereference it to use value at the address (p1 points to) as index to some array.

haccks
  • 104,019
  • 25
  • 176
  • 264
1

[*(char*)p1] is somewhat incomplete, there needs to be a variable name in front of it for the array subscription to make sense, such as for example foo[*(char*)p1].

In that case, it means:

  • convert p1 to pointer-to-char
  • dereference this pointer (giving a char value)
  • use this value as index to look up in an array

Note that using a char as index will make most compilers unhappy and cause it to emit a warning. That is because most often when a char is used as an index, it happens by error, not by intent, and also because it is implementation-defined whether char is signed or unsigned (so it is inherently non-portable, and you may end up indexing out of bounds by accident, if you assume the wrong one).

Damon
  • 67,688
  • 20
  • 135
  • 185
  • Damon if I casts to `unsigned char*` and then derefrences then it doesn't gives warning where with `char*` and `-wall` compiler emits warning. Any comment? I am using GCC – Grijesh Chauhan Jan 10 '14 at 13:42
  • @GrijeshChauhan: Casting to `unsigned char*` is **much** safer because then it's well-defined whether or not it is signed (i.e. it is not), and you cannot accidentially use e.g. index `-56` when you _really_ meant to use `200`. This is one nasty thing that could otherwise for example happen with GCC where `char` equals `signed char`. So the compiler doesn't warn any more because apart from the risk of overflowing, it's pretty safe and well-defined. – Damon Jan 10 '14 at 14:09
1

void *p1;// pointer to void or generic pointer; might be used when you want to be flexible about the data type

(char*)p1; //typecast to a char pointer; you address the memory locatuion pointed to by P1 as char

*(char*)p1; //the value at the location pointed to by p1.

Hope this helps.

Pandrei
  • 4,843
  • 3
  • 27
  • 44
0
  1. (char*)p1 is a typecast. This means, for this statement, we're treating p1 as a pointer to a character.
  2. *(char*)p1 dereferences p1, interpreting it as a char type due to the typecast (char*). A pointer points to a memory location, and dereferencing that pointer returns the value at the location in memory p1 points to.
  3. [*(char*)p1] ... Array access? is this a snippet from something larger?

This void* to someOtherType* conversion is common in C code, because malloc, used to allocate memory dynamically, returns void*.

Keeler
  • 2,102
  • 14
  • 20