Question

Dans mon programme, j'ai des objets (de la même classe) qui doivent tous avoir un identifiant unique. Par souci de simplicité et de performance, j'ai choisi d'utiliser l'adresse de l'objet comme identifiant. Et pour garder les types simples, j'utilise (void*) comme un type pour cet identifiant. En fin de compte, j'ai le code comme ceci:

class MyClass {
public:
  typedef void* identity_t;
  identity_t id() const { return (void*)this; }
}

Cela semble fonctionner très bien, mais gcc me donne un avertissement strict-aliasing. Je comprends le code serait mauvais si l'identifiant a été utilisé pour le transfert de données. Heureusement, ce n'est pas, mais la question demeure: aliasing Optimisations ont un impact sur le code produit? Et comment éviter l'avertissement?

Note: Je suis réticent à utiliser (char*) car cela impliquerait que l'utilisateur peut utiliser les données pour la copie, qu'il ne peut pas

Était-ce utile?

La solution

Vous violez constness logique de retourner l'objet mutable dans une méthode const.
Comme Neil souligne, ne jetterai est nécessaire.

class MyClass {
public:
  typedef const void* identity_t;
  identity_t id() const { return this; }
};

Autres conseils

Vous pouvez essayer d'utiliser le type uintptr_t au lieu de void*. uintptr_t est un type entier qui est défini comme étant suffisamment grande pour contenir une valeur de pointeur. Et puisque ce n'est pas en fait un pointeur, le compilateur ne sera pas signaler tout problème d'aliasing.

class MyClass {
public:
    typedef uintptr_t identity_t;
    identity_t id() const { return (identity_t)this; }
}

Essayez d'utiliser

return static_cast<void*>(this);

Cela devrait être parfaitement sûr, tout pointeur doit pouvoir être jeté à void * sans risque de perte.

Je initialement suggéré dynamic_cast(this);, mais après avoir lu un peu, je pense que cela ajoute aucun avantage, et puisqu'il est RTTI seulement ce n'est pas une bonne solution en général.

Par ailleurs, je ferais la valeur retournée const, puisque l'identité d'un objet ne peut pas changer.

Je ne vois aucun problème d'aliasing. Cependant, vous constness A bas (puisque la fonction de id est const), que le compilateur peut être mécontent. Peut-être qu'il serait préférable d'utiliser const void* comme type d'identification.

En variante, jeté l'adresse à un type entier tel que size_t. Ensuite, il n'y a plus un pointeur, et aliasing devient un non-problème.

Pourquoi ne pas utiliser MyClass * type?

Ou le type intptr_t?

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top