# Type casting!



## David John (Jul 16, 2017)

Can someone explains this casting: 
	
	



```
#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.


----------



## kpedersen (Jul 16, 2017)

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.


----------



## David John (Jul 17, 2017)

Thank you, *kpedersen *for the detailed explanation.



kpedersen said:


> 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*


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

Again, thanks for your time.


----------

