Quote:
Originally Posted by jamesbon
Code:
return ((unsigned int)(unsigned long)base & TBASE_DEFERRABLE_FLAG);
What is the above function returning.
|
It returns either a 0 or a 1.
base is declared as a pointer, but from the code it appears that
base is the combination of a pointer and a flag. The low bit of this kind of aligned pointer is always clear (on the architectures supported by this code) so that bit is available for other use.
The double cast may look strange. I think from the compiler's point of view there are four casts because IIUC, 0x1 is a signed integer constant. (I haven't looked up exact language rules on whether there are two implicit extra casts here, because it doesn't really matter).
You need an explicit cast from pointer to some integer type so that the & operator will be valid. If this is compiled in x86_64 architecture then you probably would get a warning casting directly from pointer to 32 bit integer. So casting to unsigned long and then casting again to unsigned gets you there without a warning. Then I think the compiler casts it implicitly to a signed int to do the & operator, then because the function is declared as returning unsigned int, the compiler implicitly casts the result back to unsigned.
Quote:
Originally Posted by sylvain.mazet
I personally would have written it:
Code:
return ((unsigned int) (((unsigned long)base) & TBASE_DEFERRABLE_FLAG) );
(added parenthesis).
|
Why?
That tells the compiler to generate code for a potentially less efficient operation that has the same final result.
A decent compiler at a higher optimization level will probably see through that and still generate the same code as without the extra parenthesis. So it might do no harm. But what good does it do?
It also masks intent from some later programmer who might need to understand and maintain the code. Anyone maintaining this code should understand why there are two casts. If the casts are directly sequential with no intervening operation, that greatly limits the possibilities for the intent of the casts. In this case, I think it limits the reason for two casts instead of one down to avoiding a warning.
But if you went to obvious effort to make the & operation happen after one cast but before the other, a maintenance programmer should wonder why? Is some operation here trickier than the maintenance programmer can see? Or did the original programmer intend something that this code doesn't actually accomplish? Or what?