Skip to contentSkip to conversation

question on double cast

KJ Yoann Padioleau 3 participants 6 messages May 22, 2007 Kernel janitors

lore
Share & tools
lore
#1 lore raw
Quoted 7 lines

In drivers/infiniband/hw/amso1100/c2_cm.c", line 321 there is

wr->ep_handle = (u32) (unsigned long) cm_id->provider_data;

What is the goal of this double cast ? There are plenty of such double cast in the kernel.

provider_data is type "void *", so presumably the object it points to is of type [un]signed long (meaning its size differs on different architectures). It is being cast to unsigned long to set it to that size with no sign bits, and then the low-order 32 bits are being chopped off.
_______________________________________________
Kernel-janitors mailing list [email protected]
https://lists.linux-foundation.org/mailman/listinfo/kernel-janitors

#2 lore raw
In reply to Yoann Padioleau
Quoted 5 lines · John Anthony Kazos Jr.
Quoted 5 lines

In drivers/infiniband/hw/amso1100/c2_cm.c", line 321 there is

wr->ep_handle = (u32) (unsigned long) cm_id->provider_data;

Quoted 7 lines
Quoted 2 lines

What is the goal of this double cast ? There are plenty of such double cast in the kernel.

provider_data is type "void *", so presumably the object it points to is of type [un]signed long (meaning its size differs on different architectures). It is being cast to unsigned long to set it to that size with no sign bits, and then the low-order 32 bits are being chopped off.

But isn't it equivalent to directly do

  wr->ep_handle = (u32) cm_id->provider_data;

?

Quoted 4 lines

_______________________________________________
Kernel-janitors mailing list
[email protected]
https://lists.linux-foundation.org/mailman/listinfo/kernel-janitors

_______________________________________________
Kernel-janitors mailing list
[email protected]
https://lists.linux-foundation.org/mailman/listinfo/kernel-janitors

#3 lore raw
In reply to Yoann Padioleau
Quoted 8 lines
Quoted 8 lines
Quoted 7 lines

In drivers/infiniband/hw/amso1100/c2_cm.c", line 321 there is

wr->ep_handle = (u32) (unsigned long) cm_id->provider_data;

What is the goal of this double cast ? There are plenty of such double cast in the kernel.

Quoted 8 lines
Quoted 4 lines

provider_data is type "void *", so presumably the object it points to is of type [un]signed long (meaning its size differs on different architectures). It is being cast to unsigned long to set it to that size with no sign bits, and then the low-order 32 bits are being chopped off.

But isn't it equivalent to directly do

  wr->ep_handle = (u32) cm_id->provider_data;

Depends on the endian-ness if you're on a 64-bit architecture. You'll get the high-order 32 or the low-order 32 depending on which are in the first 4 bytes of the 64-bit quantity. The only way that would be safe is if the quantity is never wider than 32 bits.
_______________________________________________
Kernel-janitors mailing list [email protected]
https://lists.linux-foundation.org/mailman/listinfo/kernel-janitors

#4 lore raw
In reply to Yoann Padioleau
Quoted 3 lines · Yoann Padioleau

But isn't it equivalent to directly do

  wr->ep_handle = (u32) cm_id->provider_data;

Try it on a 64-bit platform -- you get a warning about cast from pointer to an integer of a different size. The double-cast idiom tells the compiler you really do know what you're doing here.
_______________________________________________
Kernel-janitors mailing list [email protected]
https://lists.linux-foundation.org/mailman/listinfo/kernel-janitors

#5 lore raw
In reply to Yoann Padioleau
Quoted 8 lines · John Anthony Kazos Jr.
Quoted 3 lines

But isn't it equivalent to directly do

  wr->ep_handle = (u32) cm_id->provider_data;

Depends on the endian-ness if you're on a 64-bit architecture. You'll get the high-order 32 or the low-order 32 depending on which are in the first 4 bytes of the 64-bit quantity. The only way that would be safe is if the quantity is never wider than 32 bits.

That would be true if there were a pointer dereference involved, but it's just a cast. You'd get the low 32-bits either way, but you get a warning on 64-bit.
_______________________________________________
Kernel-janitors mailing list [email protected]
https://lists.linux-foundation.org/mailman/listinfo/kernel-janitors