Quel est le type de données uintptr_t

Qu’est-ce que uintptr_t et à quoi peut-il servir?

C’est un int non signé capable de stocker un pointeur. Ce qui signifie généralement que c’est la même taille qu’un pointeur.

Il est facultativement défini dans les normes C ++ 11 et ultérieures.

Une raison courante de vouloir un type entier pouvant contenir le type de pointeur d’une architecture est d’effectuer des opérations spécifiques à un entier sur un pointeur ou de masquer le type d’un pointeur en le fournissant comme un “handle” entier.

Edit: Notez que Steve Jessop a quelques détails supplémentaires très intéressants (que je ne vole pas) dans une autre réponse ici pour les types pédants 🙂

Première chose, au moment où la question a été posée, uintptr_t n’était pas en C ++. C’est dans C99, dans , comme un type facultatif. De nombreux compilateurs C ++ 03 fournissent ce fichier. C’est aussi en C ++ 11, dans , où c’est facultatif et qui fait référence à C99 pour la définition.

En C99, il est défini comme “un type entier non signé avec la propriété que tout pointeur valide à annuler peut être converti en ce type, puis reconverti en pointeur à vide, et le résultat sera égal au pointeur d’origine”.

Prenez cela pour dire ce qu’il dit. Il ne dit rien à propos de la taille.

uintptr_t peut avoir la même taille qu’un void* . Il pourrait être plus grand. Cela pourrait être plus petit, même si une telle implémentation C ++ se révèle perverse. Par exemple, sur une plate-forme hypothétique où void* correspond à 32 bits, mais seulement 24 bits d’espace d’adressage virtuel sont utilisés, vous pouvez avoir un uintptr_t 24 bits qui satisfait à l’exigence. Je ne sais pas pourquoi une implémentation ferait cela, mais la norme le permet.

C’est un type entier non signé exactement la taille d’un pointeur. Chaque fois que vous avez besoin de faire quelque chose d’inhabituel avec un pointeur – comme par exemple inverser tous les bits (ne demandez pas pourquoi), vous le uintptr_t en uintptr_t et le manipulez comme un nombre entier habituel, puis le uintptr_t .

Il y a déjà beaucoup de bonnes réponses à la partie “qu’est-ce que le type de données uintptr_t”. Je vais essayer de répondre à la question “à quoi cela peut-il servir?” part dans ce post.

Principalement pour les opérations binarys sur les pointeurs. Rappelez-vous qu’en C ++, il est impossible d’effectuer des opérations au niveau des bits sur les pointeurs. Pour des raisons, consultez Pourquoi ne pouvez-vous pas effectuer des opérations au niveau du pointeur sur C, et existe-t-il un moyen de contourner ce problème?

Ainsi, pour effectuer des opérations sur les pointeurs, il est nécessaire de lancer des pointeurs pour taper unitpr_t, puis effectuer des opérations au niveau du bit.

Voici un exemple de fonction que je viens d’écrire pour faire une exclusivité bit à bit ou de 2 pointeurs à stocker dans une liste chaînée XOR afin que nous puissions traverser dans les deux directions comme une liste doublement liée sans pénaliser 2 pointeurs dans chaque nœud .

  template  T* xor_ptrs(T* t1, T* t2) { return reinterpret_cast(reinterpret_cast(t1)^reinterpret_cast(t2)); }