Type casting!

Can someone explains this casting:
Code:
#define    __DECONST(type, var)    ((type)(__uintptr_t)(const void *)(var))

Ref: cdefs.h, L651

I have exauhsted all my resources trying to figure out an explanation for this type casting. I appreciate your help.
 
I can only guess but It looks like it is trying to avoid any unneeded warnings whilst also checking validity. Lets break it apart:

  • casting to (const void *) ensures that the variable passed in (var) is a const pointer (or a warning will be given (Though just tested on my cc and it doesn't give a warning))
  • casting to (__uintptr_t) casts it to an integer type large enough to hold a pointer. This eliminates const -> non-const warnings (because this is what the DECONST MACRO is intended to do.
  • casting to (type) finally converts from the integer type to the final type that the user asked for.

It seems without this, it would be possible to pass a non-const variable into DECONST which shows a confusion in the code. Also I assume some compilers might give warnings when casting away const directly (thus the uintptr_t cast).

If the compiler doesn't give warnings (because casting away a const seems to go through without warning), perhaps it is to satisfy static analysis tools such as splint etc.
 
Thank you, kpedersen for the detailed explanation.

  • casting to (const void *) ensures that the variable passed in (var) is a const pointer (or a warning will be given (Though just tested on my cc and it doesn't give a warning))
  • casting to (__uintptr_t) casts it to an integer type large enough to hold a pointer. This eliminates const -> non-const warnings (because this is what the DECONST MACRO is intended to do.
  • casting to (type) finally converts from the integer type to the final type that the user asked for.

I was confused because of (const void *) casting, since I thought the assignment was to a non-const member (bsd_kernel.h, L75) ".data". I just realized that the whole struct is const

Code:
const struct sysinit UNIQ_NAME(sysinit_##uniq) = {  \
     .func = (_func),                \
     .data = __DECONST(void *, _data)        \
};

Again, thanks for your time.
 
Back
Top