Question regarding pointer casting

I am trying some socket programming for the first time and so bear with me. I have come across quite alot of type casting similar to the one below. Can someone explain what is happening there.

((struct school*)&classroom[a])

thanks

"classroom" is an array of struct school objects. "classroom[a]" is one element of the array. "&classroom[a]" is a pointer to that one element of the array. "(struct school*)&classroom[a]" is casting that pointer as a pointer to a "struct school", which in this context, doesn't make much sense, since "&classroom[a]" is already a pointer to struct school.

Or, perhaps classroom is an array of something other than struct school, and the cast is forcing the pointer to classroom[a] to appear to be a pointer to a struct school, but that would be kinda stupid.... If school were a class, rather than a struct, that syntax could be used to cast a pointer to an object of a derived class to a pointer to one of its parent classes, but, AFAIK, that can't be done with structs.

Regards,
Ray L.

Thank you for the great explanation. Now it makes sense :slight_smile:

As Ray suggests, pointers are a little strange because of the way they are used. Some general guidelines:

  1. All pointers are the same size: they are big enough to hold a memory address of the host machine. For an Arduino, this is 2 bytes. On Windows, it will be 4 bytes.

  2. A valid pointer can only hold one of two things: a) a valid memory address, or b) null. If it's null, you
    cannot expect any valid result from a pointer operation.

  3. All pointers are scaled. That is, a pointer is "tied" to a particular type of data. If you say:

int *ptr;

ptr is tied to the int data type. Because an int is 2 bytes for an Arduino, its scalar is 2. Therefore, if you
have an array of ints and increment a pointer to that array (e.g., ptr++), the memory address being
held by the pointer is incremented by its scalar...2. If it's a pointer to char, the scalar is 1 and an
increment operation advances the memory address by 1. In both cases, however, the size of the
pointer is always 2 bytes...the size of a valid memory address.

  1. A cast is sometimes needed to adjust the scalar of a pointer. For example, malloc() is a function that
    returns a void pointer, which means it returns either null (the memory request cannot be fulfilled) or
    a pointer to an unspecified data type. The latter means the scalar has not been set. Therefore, you
    might see something like:

char *myPtr = (char *) malloc(SIZEDNEEDED);

This makes sure the void pointer is scaled to point to the char data type. (It's probably not a good idea to use malloc() on an Arduino.)

In your statement:

((struct school*)&classroom[a])

what's being done is the contents of classroom[a] as it is stored in memory is fetched and then its scalar is set to be that for a struct school data type. From then on, all pointer operations (e.g., increment, decrement, indirection, etc.) are all scaled relative to the struct school object.

econjack:
((struct school*)&classroom[a])

what's being done is the contents of classroom[a] as it is stored in memory is fetched and then its scalar is set to be that for a struct school data type. From then on, all pointer operations (e.g., increment, decrement, indirection, etc.) are all scaled relative to the struct school object.

No "contents" are fetched - only the address of classroom[a] is fetched.

Regards,
Ray L.

econjack:
There is no guarantee that all pointers are the same size. There are machines with differing pointer sizes - especially function vs data pointers. And need I mention the old Microsoft memory models?

http://c-faq.com/null/machexamp.html

@Ray: Right...that's what I meant to say. It's the lvalue that is fetched.

@Keith: Actually, what I said was:

  1. All pointers are the same size: they are big enough to hold a memory address of the host machine. For an Arduino, this is 2 bytes. On Windows, it will be 4 bytes.

While I thought that was clear by mentioning two different host machines, perhaps it would be more clear if I had said:

  1. All pointers are the same size on a given host machine: they are big enough to hold a memory address of the host machine. For an Arduino, this is 2 bytes. On Windows, it will be 4 bytes.

Even on a given host machine, pointers are not guaranteed to be the same size. Some systems have pointers of different sizes for bytes than for other objects, and C++ method pointers are generally larger than other pointers.

As chistop said. You didn't read my link, did you.