Pregunta

En mi programa, que tienen objetos (de la misma clase) todo lo que debe tener un identificador único. Por simplicidad y rendimiento, que elegimos para utilizar la dirección del objeto como identificador. Y para mantener los tipos simples, utilizo (void*) como un tipo para este identificador. Al final tengo código como este:

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

Esto parece estar funcionando bien, pero gcc me da una advertencia estricta-aliasing. Entiendo el código sería malo si se utiliza el ID de transferencia de datos. Por suerte no lo es, pero la pregunta sigue siendo: ¿será aliasing optimizaciones han producido un impacto en el código? Y cómo evitar la advertencia?

Nota: Me resisto a utilizar (char*) ya que esto implicaría que el usuario puede utilizar los datos para la copia, que no puede

!
¿Fue útil?

Solución

Se está violando constness lógica devolver el objeto como mutable en un método const.
Como señala Neil, no se necesita ningún molde.

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

Otros consejos

Se podría tratar de usar el tipo uintptr_t en lugar de void*. uintptr_t es un tipo entero que se define como ser lo suficientemente grande para contener cualquier valor de puntero. Y puesto que en realidad no es un puntero, el compilador no marcará ningún problemas de solapamiento.

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

Trate de usar

return static_cast<void*>(this);

Esto debería ser perfectamente seguro, cualquier puntero debe ser capaz de ser echado a void * sin riesgo de pérdida.

Me propuso inicialmente dynamic_cast(this);, pero después de leer un poco, creo que añade ninguna ventaja, y puesto que es RTTI, sólo que no es una buena solución en general.

Por cierto, me gustaría hacer el const valor devuelto, ya que la identidad de un objeto no puede cambiar.

No puedo ver cualquier problema de aliasing. Sin embargo, usted está desechando constness (ya que la función es id const), que el compilador podría ser infeliz. Tal vez sería mejor usar const void* como su tipo de identificación.

Alternativamente, fundido, la dirección a un tipo entero tal como size_t. Entonces ya no es un puntero, y aliasing se convierte en un no-tema.

¿Por qué no usar el tipo MyClass *?

O intptr_t tipo?

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top