So we know that the standard doesn't force pointer sizes to be equal. (here and here) (and not talking about function pointers)
I was wondering how in reality that can be an issue. We know that void *
can hold anything, so if the pointer sizes are different, that would be the biggest size. Given that, assigning a void **
to a char **
means trouble.
My question is how dangerous would it be to assume void *
and char *
have the same size? Is there actually an architecture where this is not true?
Also, 16-bit dos is not what I want to hear! ;)
void *
and char *
are guaranteed to have the same size.
void **
is not guaranteed to have the same size as char **
(but very likey on your implementation they will).
(C99, 6.2.5p27) "A pointer to void shall have the same representation and alignment requirements as a pointer to a character type [...] Pointers to other types need not have the same representation or alignment requirements."
Assigning pointers of different object types to each other is allowed as long as no alignment requirements are violated: The assignment will involve an (implicit) type conversion, so it is as (un)problematic as assigning a float
to an int
- it works in most cases but is allowed to blow up when a meaningful conversion is impossible.
char *
and void *
have compatible alignment requirements per spec, so assigning a char **
to a void **
variable (and vice versa) is never problematic. They even have compatible representation, which means in principle, accessing a char *
through an expression of type void *
- eg by dereferening a void **
which actually points to a char *
- will work as expected in most cases. Of course, the converse (accessing a void *
by dereferencing a char **
) holds true as well.
For example, the p
conversion specifier for printf()
expects a void *
and passing in an arbitrary pointer type is undefined behaviour. However, in case of char *
, it should work even on exotic architectures (eg with different pointer representations) as long as the implementation conforms to the C standard.
Where problems may arise is aliasing analysis: Due to the effective typing rules, a void **
and a char **
can't alias, and if the programmer breaks that promise, strange things may happen. One should realize that because of effective typing (aka strict aliasing), C is actually strongly typed - the type system is just very unsound (ie doesn't protect you from violating its invariants)...
来源:https://stackoverflow.com/questions/11275713/how-dangerous-is-conversion-from-void-to-char