开发者

Using (void*) as a type of an identifier

In my program, I have objects (of the same class) that must all have a unique identifier. For simplicity and performance, I chose to use the address of the object as identifier. And to keep the types simple, I use (void*) as a type for this identifier. In the end I have code like this:

class MyClass {
public:
  typedef void* identity_t;
  iden开发者_如何学编程tity_t id() const { return (void*)this; }
}

This seems to be working fine, but gcc gives me a strict-aliasing warning. I understand the code would be bad if the id was used for data transfer. Luckily it is not, but the question remains: will aliasing optimisations have an impact on the code produced? And how to avoid the warning?

Note: I am reluctant to use (char*) as this would imply the user can use the data for copy, which it can not!


You could try using the type uintptr_t instead of void*. uintptr_t is a integer type that is defined as being big enough to hold any pointer value. And since it's not actually a pointer, the compiler won't flag any aliasing problems.

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


You are violating logical constness returning the object as mutable in a const method.
As Neil points out, no cast is needed.

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


Try using

return static_cast<void*>(this);

This should be perfectly safe, any pointer should be able to be cast to void * without risk of loss.

I originally suggested dynamic_cast(this);, but after reading up a bit I think it adds no advantage, and since it's RTTI-only it's not a good solution in general.

By the way, I would make the returned value const, since the identity of an object cannot change.


I can't see any aliasing issues. However, you are casting away constness (since the id function is const), which the compiler might be unhappy about. Perhaps it'd be better to use const void* as your ID type.

Alternatively, cast the address to an integer type such as size_t. Then it is no longer a pointer, and aliasing becomes a non-issue.


Why not using type MyClass *?

Or type intptr_t?

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜