On 02.09.2015 21:55, Niall Douglas wrote:
On 2 Sep 2015 at 5:31, John Bytheway wrote:
Please do correct me if I am wrong, but I had thought that this is defined behaviour:
int a=5; void *b=(void *)(size_t) a; int c=(int)(size_t) b; assert(c==a);
This is certainly a very common pattern in C.
I believe this is implementation-defined. Based on N3797 [expr.reinterpret.cast], paragraph 5:
"A value of integral type or enumeration type can be explicitly converted to a pointer. A pointer converted to an integer of sufficient size (if any such exists on the implementation) and back to the same pointer type will have its original value; mappings between pointers and integers are otherwise implementation-defined."
The behaviour that is defined (pointer to integer and back) is the reverse of the one you want.
That's the whole point of the intermediate size_t cast. int to size_t is defined behaviour, size_t to void * is defined behaviour, void * to size_t is defined behaviour, size_t to int is defined behaviour.
Only that the original and resulting ints are equal is not guaranteed.
Older code, and still a lot of C code, directly casts between int and void * and back again, even though strictly speaking that's a no no.
Horrible code exists. No need to add yet more.