문제

내 프로그램에는 모두 고유 식별자를 가져야 하는 동일한 클래스의 개체가 있습니다.단순성과 성능을 위해 객체의 주소를 식별자로 사용하기로 결정했습니다.그리고 유형을 단순하게 유지하기 위해 다음을 사용합니다. (void*) 이 식별자의 유형으로 사용됩니다.결국 다음과 같은 코드가 있습니다.

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

이것은 잘 작동하는 것 같지만 gcc에서는 엄격한 앨리어싱 경고를 표시합니다.ID가 데이터 전송에 사용되면 코드가 좋지 않을 것이라는 것을 이해합니다.운 좋게도 그렇지는 않지만 질문은 남아 있습니다.앨리어싱 최적화가 생성된 코드에 영향을 미치나요?그리고 경고를 피하는 방법은 무엇입니까?

메모:사용하기 꺼려지네요 (char*) 이는 사용자가 복사를 위해 데이터를 사용할 수 있음을 의미하기 때문입니다.

도움이 되었습니까?

해결책

const 메소드에서 객체를 변경 가능한 것으로 반환하는 논리적 상수를 위반하고 있습니다.
Neil이 지적했듯이 캐스트가 필요하지 않습니다.

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

다른 팁

유형을 사용해 볼 수 있습니다. uintptr_t 대신에 void*. uintptr_t 포인터 값을 담을 수 있을 만큼 충분히 큰 것으로 정의된 정수 유형입니다.그리고 실제로 포인터가 아니기 때문에 컴파일러는 앨리어싱 문제에 플래그를 지정하지 않습니다.

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

사용해 보세요

return static_cast<void*>(this);

이는 완벽하게 안전해야 하며 모든 포인터를 캐스팅할 수 있어야 합니다. void * 손실 위험 없이.

원래 제안했는데 dynamic_cast(this);, 그러나 조금 읽어본 후에는 이점이 추가되지 않는다고 생각하며 RTTI 전용이므로 일반적으로 좋은 솔루션은 아닙니다.

그건 그렇고, 나는 반환 된 값을 만들 것입니다 const, 객체의 정체성은 바뀔 수 없기 때문입니다.

앨리어싱 문제는 볼 수 없습니다.그러나 당신은 불변성을 버리고 있습니다. id 함수는 const), 컴파일러가 이에 대해 만족하지 않을 수 있습니다.아마도 사용하는 것이 더 나을 것입니다. const void* 귀하의 ID 유형으로.

또는 주소를 다음과 같은 정수 유형으로 캐스팅합니다. size_t.그러면 더 이상 포인터가 아니며 앨리어싱은 문제가 되지 않습니다.

유형을 사용하지 않는 이유 MyClass *?

또는 유형 intptr_t?

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top