문제

Mingw를 사용하여 Windows에서 GTKMM 용 Cairomm을 구축하려고합니다. 컴파일은 부울의 renterpret_cast를 공허*로 수행하는 매개 변수를 갖는 함수 호출에서 나뉩니다.

cairo_font_face_set_user_data(cobj(), &USER_DATA_KEY_DEFAULT_TEXT_TO_GLYPHS, reinterpret_cast<void*>(true), NULL);

코드가 깨지는 곳이며 이유는 "Bool에서 void*까지 무효 ResterPret_cast"입니다. 이런 일이 발생하는 이유는 무엇이며 어떻게이 라인을 수정하여 컴파일 할 수 있습니까? 도움이 필요하다

도움이 되었습니까?

해결책

나는 이것이 사용자 데이터임을 알 수 있으며 값으로 수행 된 작업을 제어하고 Bool을 먼저 int로 캐스트합니다. reinterpret_cast<void *> (static_cast<int> (true)). 이렇게하면 void* 매개 변수 가이 ANSI-C 라이브러리에서 템플릿 함수를 대신한다는 점에서 의미가 있습니다. 필요한 것은 참/거짓 가치 만 있으면됩니다. 따라서,이를 잘 문서화하는 한 포인터로 일시적으로 인코딩하는 데 위험이 없어야합니다. 실제로, 당신은 이것으로 더 나을 것입니다 : reinterpret_cast<void *> (1) 또는 reinterpret_cast<void *> (+true).

다른 팁

표준에 따라 작동 해야하는 것 같습니다. 섹션 3.9.1-7은 BOOL은 적분 유형이며 5.2.10-5는 RENETERPRET_CAST를 사용하여 적분 유형의 값을 명시 적으로 포인터로 변환 할 수 있다고 말합니다. 컴파일러가 완전히 표준이 아닌 것 같습니다.

"참"을 1로 바꾸면서 도망 갈 수 있습니까? 정수와 포인터 유형을 변환하는 것은 C에서 오래되고 불명예스러운 전통이므로 C ++이므로 컴파일러를 찾는 것은 놀라운 일입니다.

또는 실제로 이것을해야한다면, (void *) true를 시도하십시오. 그런 다음 손을 씻으십시오.

reinterpret_cast는 a 나쁜 생각. 해결하려는 문제에 대해 더 자세히 알려 주시면 재 해석에 의지하지 않고 솔루션을 찾을 수 있습니다. 부울을 void*로 변환하고 싶습니까?

내가 이것에 대해 불평하는 유일한 컴파일러는 GCC (GCC 3.4.5를 사용한 mingw)입니다. 왜 그런지 잘 모르겠습니다. 표준은 이것을 허용한다는 것을 명확하게 나타내는 것 같습니다.

3.9.1 기본 유형

...

유형 BOOL, Char, WCHAR_T 및 서명되지 않은 정수 유형을 통합적으로 통합 유형이라고합니다.

5.2.10 재 해석 캐스트 :

...

적분 유형 또는 열거 유형의 값은 포인터로 명시 적으로 변환 될 수 있습니다.

즉, Monjardin의 해결 방법 사용 reinterpret_cast<void *> (static_cast<int> (true)) 또는 reinterpret_cast<void *> (1) 합리적인 해결 방법입니다.

캐스트가 의미가 없기 때문에 실패합니다. 부울 참/거짓 값을 취하고 컴파일러에게 이것을 포인터로 해석하도록 요청합니다. 두 사람은 원격으로 관련이 있습니다.

최신 버전의 컴파일러를 사용해보십시오. 방금 테스트 했고이 캐스트는 최소한 GCC 4.1 이상에서 작동합니다. 그래도 GCC 버전이 MINGW 버전에 어떻게 매핑되는지 정확히 모르겠습니다.

어떤 상황에서는 컴파일러가 코드에 대해 경고하거나 오류가 발생하는 것이 매우 바람직합니다. reinterpret_cast<void*>(true), 이 코드는 분명히 합법적 인 C ++입니다. 예를 들어, 64 비트 플랫폼으로 포팅하는 데 도움이됩니다.

64 비트 포인터를 포인터보다 작은 적분 유형으로 시전합니다 (예 : int 또는 bool)는 종종 버그입니다 : 당신은 포인터의 가치를 자르고 있습니다. 또한 C ++ 사양은 포인터를 더 작은 적분 유형으로 직접 캐스트 할 수 있다고 보장하지 않는 것 같습니다 (강조 추가).

5.2.10.4. 포인터는 모든 적분 유형으로 명시 적으로 변환 될 수 있습니다. 그것을 붙잡을만큼 충분히 큽니다. 매핑 함수는 구현 정의됩니다.

마찬가지로, 더 작은 적분 유형을 64 비트 포인터로 캐스팅합니다 ( reinterpret_cast<void*>(true))은 종종 버그입니다. 컴파일러는 포인터의 상단 비트를 무언가로 채워야합니다. 제로 필기 또는 사인-류드가 있습니까? 메모리 매핑 된 I/O 액세스 또는 DMA에 대한 저수준 플랫폼 별 코드를 작성하지 않는 한, 당신은 보통 호피를하는 것과 같은 일을하지 않는 한, 당신은 일반적으로 이것을하고 싶지 않습니다 (부울을 포인터에 넣는 것과 같이 ). 그러나 C ++ 사양은 구현 정의 (각주 생략) 이외 의이 사례에 대해 많이 말하지 않는 것 같습니다.

5.2.10.5. 적분 유형 또는 열거 유형의 값은 포인터로 명시 적으로 변환 될 수 있습니다.*

포인터는 충분한 크기의 정수 (구현에 존재하는 경우)의 정수로 변환되고 동일한 포인터 유형으로 되돌아 가면 원래 값이 있습니다. 포인터와 정수 사이의 매핑은 구현 정의됩니다.

@monjardin이 제안했습니다 reinterpret_cast<void*>(static_cast<int>(true)). 오류의 원점이 적분 유형의 크기와 포인터 크기 사이의 불일치 인 경우, 이것은 대부분의 32 비트 플랫폼에서 작동합니다 (여기서 둘 다 int 그리고 void* 32 비트이지만 대부분의 64 비트 플랫폼에서 실패합니다 (어디에서 int 32 비트이고 void* 64 비트). 이 경우 교체 int 이 표현에서 포인터 크기의 정수 유형과 같은 표현에서 uintptr_t 또는 DWORD_PTR (Windows에서)는 작동해야합니다. bool 포인터 크기의 정수가 허용되며 포인터 크기의 정수와 포인터 사이의 변환도 허용됩니다.

이후의 GCC 버전에는 다음이 있습니다 경고 억제 옵션, 하지만 C ++가 아닙니다:

-Wno-Int-to-Pointer-Cast (C 및 Objective-C 만 해당)
캐스트에서 다른 크기의 정수의 포인터 유형에 이르기까지 경고를 억제하십시오.

-wno-pointer-to-int-cast (C 및 Objective-C 만 해당)
포인터에서 다른 크기의 정수 유형에 이르기까지 캐스트에서 경고를 억제하십시오.

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