On 2015-09-02 14: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.
To be clear, do you mean standard-defined (as opposed to implementation-defined)? I'm assuming so. Then, as Andrey pointed out, the result is not defined. Only integer values that were obtained from a previous cast from a pointer can be safely cast to a pointer type (unless you have evidence from elsewhere in the standard to suggest more). If you actually want defined behaviour here, I think you should use a union { int; void*; }. That ought not to have any performance penalty. That said, I imagine that in practice the implementation-defined behaviour of what you're doing will be what you want in any implementation where using AFIO makes sense. John
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.
Niall
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost