77 votes

Lorsque est un entier<->pointeur de la fonte correcte?

La commune de folklore dit que:

  • Le type de système existe pour une raison. Les entiers et les pointeurs sont des types distincts, casting entre eux, c'est une faute professionnelle dans la majorité des cas, peut indiquer une erreur de conception et doit être évitée.

  • Même lorsque cette distribution est effectuée, aucune hypothèse ne doit être faite à propos de la taille des entiers et des pointeurs (casting void* de int est le moyen le plus simple pour rendre le code échouer sur x64), et au lieu de int il faut utiliser intptr_t ou uintptr_t de stdint.h.

Sachant que, quand est-il réellement utile d'effectuer de telles jette?

(Remarque: le fait d'avoir un peu plus court code pour le prix de la portabilité ne compte pas comme "utiles".)


Un cas que je connais:

  • Certains sans verrouillage multiprocesseur algorithmes d' exploiter le fait que 2+-octet-alligned pointeur a une certaine redondance. Ils ont ensuite utiliser la plus faible de bits de l'aiguille, en tant que booléen drapeaux, par exemple. Avec un processeur avec un jeu d'instructions, cela peut éliminer la nécessité d'un mécanisme de verrouillage (qui serait nécessaire si le pointeur et le drapeau booléen ont été séparées).
    (Remarque: Cette pratique est même possible de le faire en toute sécurité en Java via java.util.de façon concomitante.atomique.AtomicMarkableReference)

Quelque chose de plus?

38voto

PlasmaHH Points 8426

J'ai parfois fonte des pointeurs vers des entiers quand ils en quelque sorte besoin de faire partie d'un hashsum. Aussi je les jetai à des entiers de faire quelques bitfiddling avec eux sur certains implemetnations où il est garanti que les pointeurs de toujours avoir un ou deux de rechange bits à gauche, là où je peux coder AVL ou RB Arbre de l'information dans la gauche/droit des pointeurs au lieu d'avoir un membre supplémentaire. Mais tout cela est de la mise en œuvre spécifique, que je vous recommande de ne jamais penser à elle comme une sorte de solution commune. Aussi j'ai entendu dire que parfois danger pointeurs peuvent être mis en œuvre avec une telle chose.

Dans certaines situations, j'ai besoin d'un ID unique par objet que je passe le long de serveurs par exemple que mon id de la demande. En fonction du contexte, quand j'en ai besoin pour économiser de la mémoire, et il en vaut la peine, j'utilise l'adresse de mon objet en tant que tel un id, et ont généralement de le jeter à un entier.

Lorsque vous travaillez avec des systèmes embarqués (comme dans les appareils photo canon, voir chdk) il y a souvent de la magie addesses, donc un (void*)0xFFBC5235 ou similaire est souvent trouvé il y a trop

edit:

Viens de tombé (dans mon esprit) sur pthread_self() qui renvoie une pthread_t qui est généralement un typedef pour un entier non signé. En interne, mais il est un pointeur vers un thread struct, représentant le thread en question. En général, il pourrait utilisé ailleurs pour une opaque poignée.

15voto

Flexo Points 39273

Il pourrait être utile lors de la vérification de l'alignement des types, en général, de sorte que les mal alignées mémoire se fait prendre avec une assertion plutôt que de simplement SIGBUS/SIGSEGV.

E. g.:

#include <xmmintrin.h>
#include <assert.h>
#include <stdint.h>

int main() {
  void *ptr = malloc(sizeof(__m128));
  assert(!((intptr_t)ptr) % __alignof__(__m128));
  return 0;
}

(Il est clair que je n'aurais pas fait juste jouer sur l' malloc si c'était vrai code, mais il illustre le point)

12voto

Strilanc Points 7161

Le stockage d'une liste doublement chaînée à l'aide de la moitié de l'espace

Un XOR Liste Liée combine le next et prev pointeurs vers une valeur unique de la même taille. Il le fait par xor-ment les deux pointeurs ensemble, ce qui nécessite de les traiter comme des entiers.

8voto

Rudy Velthuis Points 11477

Par exemple, dans Windows, par exemple, l' SendMessage() et PostMessage() fonctions. Ils prennent un HWnd (à un handle de fenêtre), un message (une intégrale), et de deux paramètres pour le message, un WPARAM et LPARAM. Les deux types de paramètres sont partie intégrante, mais parfois vous devez passer des pointeurs, selon le message que vous envoyez. Ensuite, vous devrez jeter un pointeur vers un LPARAM ou WPARAM.

Je voudrais généralement l'éviter comme la peste. Si vous avez besoin de stocker un pointeur, utilisation d'un pointeur de type, si c'est possible.

8voto

R.. Points 93718

Le cas le plus utile dans mon esprit, c'est celle qui a vraiment le potentiel pour faire des programmes beaucoup plus efficace: un certain nombre de standards et de la bibliothèque commune interfaces prendre qu'un seul void * argument qui ils vont passer de nouveau à une fonction de rappel de quelque sorte. Supposons que votre rappel n'a pas besoin de grande quantité de données, il suffit d'un seul argument entier.

Si la fonction de rappel qui va arriver avant le retour de fonction, vous pouvez tout simplement passer l'adresse d'un local (automatique) int variable, et tout est bien. Mais le meilleur dans le monde réel exemple de cette situation est - pthread_create, où le "rappel" s'exécute en parallèle et vous n'avez aucune garantie qu'il sera en mesure de lire l'argument par le pointeur avant pthread_create de rendement. Dans cette situation, vous avez 3 options:

  1. malloc d'un seul int et la nouvelle thread de lecture et d' free .
  2. Passer un pointeur à un appelant-local de la structure contenant l' int et un objet de synchronisation (par exemple, un sémaphore ou un obstacle) et l'attente de l'appelant sur elle après l'appel de pthread_create.
  3. Fonte de l' int de void * et passer par valeur.

L'Option 3 est infiniment plus efficace que l'une ou l'autre des choix, qui impliquent un supplément étape de synchronisation (pour l'option 1, la synchronisation est en malloc/free, et sera presque certainement impliquer une certaine coût puisque les allouer et de libérer du fil ne sont pas les mêmes).

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X