On Sun, 19 Aug 2007, David Brownell wrote:
> On Sunday 19 August 2007, Anton Altaparmakov wrote: > > > > > > ISTR we don't *have* a uintptr_t on all architectures, or that would > > > be the appropriate thing to use in these 32/64 bit ABI scenarios. > > > > > > > > >> Use unsigned long or uintptr_t instead. > > > > > > I suspect you mean "unsigned long long"... > > > > No he doesn't.  "unsigned long" is guaranteed to be large enough to  > > hold a pointer (at least on Linux anyway). Yup, sizeof(long) >= sizeof(void *) should always be true in Linux C. I bet a lot of code out there depends on this. BTW, just curious to know, but which (if any) are the platforms that have sizeof(long) > sizeof(void *)? [i.e. greater-than but not equal?] The reason I ask is that gcc will also complain (understandably so) with "warning: cast from pointer to integer of different size" i.e. even if it's a conversion from smaller size to greater size, and not really a case of truncation. Therefore, I wonder if the stricter assertion: sizeof(long) == sizeof(void *) holds true for Linux C, actually. > And yet when I used that, I got compiler warnings on some systems. > > ISTR that was the first solution I tried, but GCC really wanted to > issue warnings. Either about casting 64-bit to pointer, or about > casting it to "unsigned long", either way lost precision. Hmm, if you could fish out those testcases ... > > On a 32-bit arch "unsigned long" is 32-bit and pointers are 32-bit. > > > > On a 64-bit archi "unsigned long" is 64-bit and pointers are 64-bit. > > So with 32 bit userspace "unsigned long long" is the type to use > when talking to a 64-bit kernel; and with pure 64-bit code, it's > enough to write "unsigned long". > > I'm fairly sure that's the root cause of the pain I recall here; > but I'd have to run experiments again to verify that. I suspect the root cause of the pain was that you used "int" or "long" to talk between kernel and userspace in the first place. You shouldn't, we have __u32 / __u64 / etc for that. Satyam