Conversion d’un pointeur non `avoid` en` uintptr_t` et inversement

Il existe deux règles standard C liées:

Norme C99, 6.3.2.3 :

Un pointeur à annuler peut être converti en ou à partir d’un pointeur vers tout type d’object ou incomplet. Un pointeur sur un type d’object incomplet ou incomplet peut être converti en un pointeur à annuler et inverser; le résultat doit être égal au pointeur d’origine.

Et 7.20.1.4 :

Le type suivant désigne un type entier non signé avec la propriété selon laquelle tout pointeur valide sur void peut être converti en ce type, puis reconverti en pointeur en void, et le résultat sera comparable au pointeur d’origine: uintptr_t

Cela signifie que le code suivant est conforme:

 int *p = NULL; void *q = (void*)p; uintptr_t s = (uintptr_t)q; 

Mais a-t-il vraiment besoin de la dissortingbution en deux étapes? Le compilateur effectuera-t-il une conversion intermédiaire implicite si:

 int *p = NULL; uintptr_t s = (uintptr_t)p; 

(Eh bien, ce sera probablement le cas pour la plupart des compilateurs, mais ma question concerne la conformité standard)

Je ne risquerais pas ça. La norme indique clairement ce qui est permis et ce qui n’est pas permis.

Écrire uintptr_t s = (uintptr_t)(void*)p; signale au lecteur de votre code que vous savez ce que vous faites.

Toute implémentation qualité de qualité générale traitera les conversions entre uintptr_t et un type non vide comme si elles avaient été converties via void* . La norme traite le comportement dans cette situation, et de nombreux autres impliquant des pointeurs, comme un problème de qualité d’implémentation, et s’attend à ce que les personnes cherchant à écrire des implémentations de qualité soient capables de reconnaître les situations dans lesquelles il existe un moyen évident, sensé et utile. pour qu’un programme se comporte sans que la norme ait à les énumérer explicitement. Ils reconnaissent également qu’il est possible de produire une implémentation conforme mais de qualité médiocre au sharepoint devenir inutile.

Bien qu’il soit possible d’avoir une implémentation dans laquelle les conversions entre uintptr_t et tout type de pointeur non vide se comportent de manière arbitraire selon le choix de l’implémenteur, toute personne qui produit une implémentation dans laquelle de telles conversions ne fonctionnent pas de la manière habituelle et qui échoue pour documenter une bonne raison pour une telle différence, doit être reconnu comme un vandal qui tente de saper la langue avec une mise en œuvre de mauvaise qualité. Les programmeurs ne devraient pas se sentir obligés d’apaiser un tel comportement; à moins que ou jusqu’à ce qu’il soit vu pour ce qu’il est, il ira de pire en pire jusqu’à ce que la langue devienne totalement inutile.