Um caso de uso típico (em aplicativos hospedados de código de usuário) para converter algum ponteiro para intptr_t
(de <stdint.h>
padrão C99 ou C11 header) é computar algum código hash nesse ponteiro:
uint32_t hash_of_foo_ptr(struct foo_st*foo) {
return (uint32_t) (((intptr_t)foo)*613) ^ ((intptr)foo%51043));
}
Por motivos históricos (por exemplo, o Linux veio antes de C99), o kernel Linux usa unsigned long
em vez de uintptr_t
(o tipo integral não assinado do mesmo sizeof
como ponteiros) ou intptr_t
Além disso, o espaço do usuário para as transmissões no espaço do kernel (por exemplo, argumentos do syscalls) está no kernel do Linux em termos de long
ou unsigned long
(novamente, é melhor pensar em intptr_t
ou% código%). Mesmo quando você transmite endereços do espaço do usuário para o espaço do kernel, é necessário pensar nos espaços de endereço e na memória virtual (e está se tornando complexo, já que o espaço do usuário e o código do kernel residem em diferentes espaços de endereço).
Uma citação sobre o tema de LDD3 :
Although, conceptually, addresses are pointers, memory administration is often better accomplished by using an unsigned integer type; the kernel treats physical memory like a huge array, and a memory address is just an indexinto the array. Furthermore, a pointer is easily dereferenced; when dealing directly with memory addresses, you almost never want to dereference them in this manner. Using an integer type prevents this dereferencing, thus avoiding bugs. Therefore, generic memory addresses in the kernel are usually unsigned long , exploiting the fact that pointers and long integers are always the same size, at least on all the platforms currently supported by Linux.
Note que o kernel do Linux não é codificado em C99 portável padrão academicamente hospedado. É um programa independente, codificado com alguns compiladores particulares C em mente ( GCC e talvez também no futuro Clang / LLVM ...).
O kernel do Linux está usando algumas extensões do GCC para C (por exemplo, uintptr_t
-s , builtins, computado goto-s, etc ...), talvez embrulhado com macros. A maioria dessas extensões também é suportada pelo Clang / LLVM .
Novatos do Kernel & lkml são provavelmente bons lugares para perguntar sobre isso.