I've been scratching my head for a while trying to figure out this bit of code (I've snipped the irrelevant sections), and I think I've finally managed to wrap my head around it, but I had a few questions I wanted to ask. Here it is:
Code:
#define DECL_CONST_CAST_OF(CCTYPE) \
union { const CCTYPE *__c_ptr; CCTYPE *__ptr; } __ptr_u
#define const_cast(b) (__ptr_u.__c_ptr = (b), __ptr_u.__ptr)
static const opcode_t *
default_unpack(ARGMOD(PackFile_Segment *self), ARGIN(const opcode_t *cursor))
{
DECL_CONST_CAST_OF(opcode_t);
self->op_count = PF_fetch_opcode(self->pf, &cursor);
self->itype = PF_fetch_opcode(self->pf, &cursor);
self->id = PF_fetch_opcode(self->pf, &cursor);
self->size = PF_fetch_opcode(self->pf, &cursor);
if (self->size == 0)
return cursor;
self->data = const_cast(cursor);
cursor += self->size;
return cursor;
}
So, from what I have been able to gather, here is what is happening --
Essentially, the two macros would get expanded to:
Code:
union {
const opcode_t *__c_ptr;
opcode_t *__ptr;
} __ptr_u
and
Code:
self->data = (__ptr_u.__c_ptr = cursor, __ptr_u.__ptr)
The second macro would place
cursor into the field of the union that was accepting a
const opcode *, so everything would be OK w/ the compiler, since the types && qualifiers match. Then
ptr_u.__ptr, since it is on the right-hand side of the comma, would be the actual value of the expression, and that is what would go into
self->data -- i.e. a regular (non-const)
opcode_t * .
But I am having trouble understanding the implications of this. My questions are:
1) Am I correctly understanding this to mean that
self->data is a pointer that has read/write access to the memory that
cursor is pointing to, so that they point to the same place, but only
self->data has permission to write to it?
2) What is happening internally here? Is there some sort of 'permissions flag' that the compiler flips on/off when they cast away the
const via this union trick? I used to think that
const marked the memory as non-writable somehow, but obviously not, since
self->data and
cursor both point to the same thing ... so where are these 'permissions' set on?
Thanks,
jrtayloriv