pointers casting

2

I can not understand why casting between pointers has some impact on the code, and just to leave the code readable, for example, this line of a function:

 void* getPhysicalAddress (pdirectory* dir, uint32_t virt) {

   ... 
   ... 

   return (void*) ((uint32_t*) (pagedir[virt >> 22] & ~0xfff))[virt << 10 >> 10 >> 12];


}

Why do (void*)((uint32_t*)(..) for example? Would you like to know when to use the cast of pointers ?

    
asked by anonymous 04.08.2016 / 20:26

2 answers

3

First you should understand that the types ( int , char , long , etc.) have a size defined by the platform, some maintains their size on all platforms, such as% of char .

The pointers point to memory address, however, you need to tell what kind of memory region you want to point to, so the compiler knows how to handle the information that the pointer points to (allocations, calculations, etc.). ).

The type 8 bits is an exception to the type rules. The type void has a size of void , however, it does not store any data. The pointer of type 1 byte can only point to another pointer of the same type (this rule is for all types), it is usually used to "generalize" data. It is used a lot when you do not know what type of data you will receive, however, when you receive it, it is necessary to make a void for the type of the variable that is receiving this data, so that it can be manipulated (allocations, calculations , assignments, etc.).

The cast is to force a variable to be a different type than it was declared. It is used to optimize operations and even make it possible to do operation between two or more variables without the result being unexpected.

Regarding your line of code, I'll break it down into four to do an analysis:

First part:

In this section, the value of the variable cast is shifted to take the 10 most significant bits of the data contained in the variable and the resulting value will serve as the index for the virt array. From the value contained in pagedir index pagedir two more operations are done, one of negation (~) and one AND (&) and will result in another value, which seems to me to be another address:

pagedir[virt >> 22] & ~0xfff

Second part:

The result of the first part, it seems to me, returns an address, so in that second part another memory region is being indexed (pointed) from that address:

(pagedir[virt >> 22] & ~0xfff))[virt << 10 >> 10 >> 12];

The parentheses, around [virt >> 22] and operations done with it, mean that the address resulting from these operations will be indexed by the brackets and within the brackets an indexing is done which is equivalent to a pointer arithmetic: pagedir

Third part:

At this point the cast of (...)[virt << 10 >> 10 >> 12] is saying that the indexed memory region (pointed), as stated in the second part, should be treated in the base (size) of (uint32_t*) _t, then any operation (allocations, calculations, assignments, etc.) will be performed on this basis:

((uint32_t*) (pagedir[virt >> 22] & ~0xfff))[virt << 10 >> 10 >> 12];

Part Four:

Finally, the whole operation is pointed to by a uint32 type, because the function returns a data of this type and, in my view, this function is letting those who receive their return define how they want to store the returned value, so whoever receives this return will have to void to some type:

return (void*) ((uint32_t*) (pagedir[virt >> 22] & ~0xfff))[virt << 10 >> 10 >> 12];

I'll leave a link for you to find more information about pointers: Programming in C / Pointers

    
04.08.2016 / 21:18
0

Casting a pointer to (void *) is required for some functions that use a "generic pointer" as an argument. A pointer, in addition to pointing to an address of a variable, also stores the memory size that that variable occupies. When we do the casting, we are changing the size of the variable that the pointer stores.

    
04.08.2016 / 20:32