2014-12-11 2 views
3

콜백을 사용하는 라이브러리 (ENet)를 사용하고 있습니다. 이러한 콜백 함수에서 사용자 데이터 용 void *가 포함 된 구조체를 전달합니다. 그 변수를 사용하고 싶지만 포인터가 아닙니다. 메모리를 할당하기를 원하지 않기 때문에 size_t를 저장하기 위해 void *의 공간을 직접 사용하고 싶습니다.엄격한 앨리어싱 경고를 피할 수있는 방법이 있습니까?

그러나 예상대로 void * 변수를 size_t 변수로 캐스팅하면 엄격한 별칭 경고가 표시됩니다. 그리고 콜백의 구조체는 void * 이외의 다른 것으로 그것을 액세스하기위한 공용체를 제공하지 않습니다.

나는이 경고를 완전히 해제 할 수 있음을 알고 있지만, 나는이 특별한 경우를 위해 침묵으로하고 싶다. 경고를 피하기 위해 컴파일러가 의도적임을 알 수있는 이런 종류의 캐스트를 작성하는 방법이 있습니까?

편집 : 여기

내가 할 노력하고있어의 예입니다.

size_t& offset = reinterpret_cast<size_t&>(packet->userData); 

이 작동하지만 경고를 제공합니다 : I는 사용자 값을 편집 할 수 있어야하기 때문에, 나는 또한에 대한 참조를 잡으려고 노력하면서 size_t로 캐스팅하고 있습니다. 예상대로

+0

어떤 언어로 작업하고 있습니까? –

+0

C++, C 라이브러리 사용 – Nairou

+0

엄격한 앨리어싱이 무엇인지 이해하고 있습니까? 왜 그것을 위반하는 것이 나쁜 생각입니까? 경고를 비활성화하면 코드가 미쳐 버릴 수 있습니다. 컴파일러는'size_t &'에 대한 변경으로 인해'void * &'가 변경 될 수 있다고 가정하고 변경 사항을 무시하고 레지스터에'void * & '값을 저장합니다. .. – Yakk

답변

4

그러나, 나는 빈 역 참조 * size_t로 변수에 변수, 나는 엄격한 별명 경고를 얻을. 당신은 그냥 일반 정수를 수송하기 위해 void * 자체를 사용하려면

, 당신이 그것을 역 참조 싶지 않아, 당신은 intptr_t 표준으로, 가장 좋은 건입니다 (적절한 정수 유형으로 캐스트 할 void *을 통한 왕복 여행에서 생존 할 수 있습니다.

intptr_t magic=42; 
register_callback(&myfunc, (void *)magic); 

// ... 

void myfunc(void *context) 
{ 
    intptr_t magic=(intptr_t)context; 
    // ... 
} 

- void * (같은 char *unsigned char *)를 대상 있지 않기 때문에 게다가, 당신은 아마 당신의 코드에서 뭔가 이상한 일을

, (당신이 C++를 좋아하는 경우에 스타일 캐스트, 그 모든 reinterpret_cast 것) 엄격한 앨리어싱 규칙 (다른 포인터를 별칭으로 지정할 수 있음)


업데이트 여기

내가 할 노력하고있어의 예입니다.

size_t& offset = reinterpret_cast<size_t&>(packet->userData); 

이 작동하지만 경고를 제공합니다 : I는 사용자 값을 편집 할 수 있어야하기 때문에, 나는 또한에 대한 참조를 잡으려고 노력하면서 size_t로 캐스팅하고 있습니다. 심지어 size_tvoid *는 (보장되지 않음), 이는 이식 할 수없는 동일한 크기 및 배향을 요구 한 것으로 가정

아니; 앨리어싱 void *&size_t &과 함께 사용할 수 없습니다 (또한 참조에서 숨겨져 있기 때문에 특히 바람직하지 않습니다).

정말로 이것을 할 필요가 있다면, 컴파일러에 대한 조건을 찾아야합니다. 예를 들어 gcc에서 -fno-strict-aliasing과 함께이 파일을 컴파일 할 수 있습니다. 단순히 경고를 비활성화 (카펫 아래 잠재적 문제 숨기기)하는 대신 엄격한 앨리어싱에 대한 컴파일러 가정을 비활성화하여 비 관련 유형에 대한 포인터/참조가 동일한 내용을 가리키는 경우에도 생성 된 코드가 올바르게 작동합니다.

+0

감사합니다. 나는 잘못 입력 했어, 나는 캐스트를하고 있고, 역 참조가 아니다. 도움이 필요한 경우에 대비하여 내가 실제로하려고하는 것을 보여주기 위해 해당 게시물을 업데이트 할 것입니다. – Nairou

+0

@Nairou : 이제 명확 해졌습니다. 대답이 업데이트되었습니다. –

+0

설명해 주셔서 감사합니다! 아는 한, 참조를 사용하는 대신 별도의 단계에서 변수를 가져오고 업데이트하는 코드를 편집했습니다. 모두 좋다! – Nairou

관련 문제