Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why cast a pointer to an unsigned long, then to a uint32_t?

Tags:

c

linux

The Linux manual page for futex(2) describes the interpretation of the fourth argument as follows:

  For several blocking operations, the timeout argument is a pointer
  to a timespec structure that specifies a timeout for the
  operation.  However,  notwithstanding the prototype shown above,
  for some operations, the least significant four bytes of this
  argument are instead used as an integer whose meaning is
  determined by the operation.  For these operations, the kernel
  casts the timeout value first to unsigned long, then to uint32_t,
  and in the remainder of this page, this argument is referred to as
  val2 when interpreted in this fashion.

I assume the purpose of the two casts is just to get the bottom 32 bits of the pointer, but why does that need to be done with two casts rather than one?

What is the difference between this

uint32_t x = (uint32_t) (unsigned long) p;

and this?

uint32_t x = (uint32_t) p;
like image 273
pjc Avatar asked Sep 14 '25 12:09

pjc


1 Answers

(uint32_t) p risks undefined behavior (UB).


Consider from the C spec:

Any pointer type may be converted to an integer type. Except as previously specified, the result is implementation-defined. If the result cannot be represented in the integer type, the behavior is undefined. The result is not required to be in the range of values of any integer type. C23dr § 6.3.2.3 6

Since uint32_t may be narrower than a pointer, to avoid the UB of "If the result cannot be represented in the integer type, the behavior is undefined.", it makes sense to first cast to a wide type. unsigned long seems a weak choice compared to unsigned long long, uintmax_t, or even (u)intptr_t when it exists.

In any case, it appears the first cast is to avoid UB. The uint32_t is simply to toss upper bits and only retain the least significant 32.

like image 146
chux - Reinstate Monica Avatar answered Sep 17 '25 05:09

chux - Reinstate Monica