When is it legal to enter a pun with a pointer to a pointer in C?

In program C, I have a structure

typedef struct { void *payload; // opaque, real type known to callbacks ... some stuff ... } MiddleMan; 

To create some type of security veneer, I could create getters and setters

 CbData *get_cb_data(const MiddleMan *mm){ return mm->payload; } void set_cb_data(MiddleMan *mm, CbData *cbd){ mm->payload = cbd; } 

Or I can try to do this with one based on access pointers

 CbData **cb_data(MiddleMan *mm){return (CbData**)&mm->payload;} 

Now the second solution looks rougher than the first, and also restricts users to non-constant mm , even if they just want to read. But my question is, is this even legal C?

I'm sure you can get away from it in any architecture where void* has the same size and format as CbData* . But can anyone give a clear explanation why this (or not) is really at all?

+6
source share
1 answer

Generally, you should not do this. A void** may have a different alignment requirement with CbData** . Explicit casts may lead to a different address.

C standard 6.2.5.27:

A pointer to a void must have the same representation and alignment as a pointer to a character type. 39) Similarly, pointers to qualified or unskilled versions of compatible types have the same representation and alignment requirements. All pointers to structure types must have the same representation and alignment as each other. All pointers to union types should have the same presentation and alignment requirements as each other. pointers for other types do not have to have the same representation or alignment requirements.

+4
source

Source: https://habr.com/ru/post/953240/


All Articles