3

私のプログラムには、すべて一意の識別子を持つ必要がある (同じクラスの) オブジェクトがあります。簡単さとパフォーマンスのために、オブジェクトのアドレスを識別子として使用することにしました。型を単純にするために(void*)、この識別子の型として を使用します。最後に、次のようなコードがあります。

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

これは問題なく動作しているように見えますが、gcc から厳密なエイリアスの警告が表示されます。IDがデータ転送に使用された場合、コードが悪いことを理解しています。幸いなことにそうではありませんが、疑問が残ります。エイリアシングの最適化は、生成されるコードに影響を与えるのでしょうか? そして、警告を回避する方法は?

注:(char*)これは、ユーザーがデータをコピーに使用できることを意味するため、使用するのは気が進まないのですが、それはできません!

4

5 に答える 5

4

uintptr_tの代わりにtype を使用してみてくださいvoid*uintptr_t任意のポインター値を保持するのに十分な大きさとして定義されている整数型です。実際にはポインターではないため、コンパイラーはエイリアシングの問題にフラグを立てません。

class MyClass {
public:
    typedef uintptr_t identity_t;
    identity_t id() const { return (identity_t)this; }
}
于 2009-12-08T09:07:26.763 に答える
3

const メソッドで可変としてオブジェクトを返す論理 constness に違反しています。
ニールが指摘するように、キャストは必要ありません。

class MyClass {
public:
  typedef const void* identity_t;
  identity_t id() const { return this; }
};
于 2009-12-08T13:03:40.467 に答える
2

使ってみて

return static_cast<void*>(this);

void *これは完全に安全である必要があり、損失のリスクなしに任意のポインターにキャストできる必要があります。

私は最初に を提案dynamic_cast(this);しましたが、少し読んだ後、利点はないと思います.RTTIのみであるため、一般的には良い解決策ではありません.

ちなみに、constオブジェクトの ID は変更できないため、戻り値を にします。

于 2009-12-08T09:04:13.853 に答える
1

エイリアシングの問題は見られません。ただし、(関数が const であるため) constness をキャストしているためid、コンパイラはこれに不満を持っている可能性があります。おそらくconst void*、ID タイプとして使用する方がよいでしょう。

または、アドレスを などの整数型にキャストしますsize_t。その後、ポインターではなくなり、エイリアシングは問題になりません。

于 2009-12-08T10:41:25.320 に答える
0

type を使用しないのはなぜMyClass *ですか?

またはタイプintptr_t

于 2009-12-08T09:04:55.233 に答える