2010-05-01 6 views
2

어딘가에 코드 라인에, 나는 ...이 C++ 구문은 무엇을합니까?

//void* v = void* value from an iterator 
int i = (int)(long(v)) 

이 contruct이 가능한 어떤 목적을 제공 할 수 있습니다,이 구조를 건너 왔어요?

그냥 int(v)을 사용하지 않는 이유는 무엇입니까? 왜 캐스트 먼저 long에?

+5

더 자세한 정보를 제공 하시겠습니까? –

+0

@James Morris : 이것이 필요한 모든 정보라고 생각합니다 ... 컨테이너에서 'void *'값을 얻고 있습니다. 그 void * 값은 실제로는 정수입니다 (void *로 푸시되었습니다). 이제 정수를 되찾아주세요. 나는이 문제에 대해 이미 언급했다. – Moeb

+2

차라리 두 개의 다른 캐스트 표기법을 하나의 식으로 혼합하는 이유를 묻고 싶습니다. – AnT

답변

8

경고음을 대부분 차단합니다.

sizeof (int) < sizeof (long) 및 sizeof (long) == sizeof (void *)를 사용하는 32 비트 아키텍처를 가정하면 void *를 int로 캐스팅하면 경고가 표시되고 캐스트하면 경고가 표시되지 않을 수 있습니다 당신이 잘리지 않는 한 무효 *. 그런 다음 long에서 int로 명시 적으로 캐스팅하여 제거 된 int (가능한 절단)에 long을 지정하는 경고를받습니다.

컴파일러를 모르면 말하기 어렵지만 경고를 방지하는 데 필요한 여러 단계의 캐스트를 보았습니다. 컴파일러가 무엇을해야한다고 생각하는지 구조를 변환하고 컴파일러가 말하는 것을 보려고하지 마라. (물론 컴파일러가 똑같고 경고 수준이 같다면 원래 프로그래머의 마음에 있었던 것을 해결하는 데 도움이된다. 그들은 그대로).

+0

@Len Holgate : 사용중인 컴퓨터에서 sizeof'void * = 8, long = 8, int = 4'을 사용하십시오. – Moeb

3

eeevil.

대부분의 아키텍처에서 포인터는 다른 종류의 숫자로 간주 될 수 있습니다. 대부분의 아키텍처에서 long은 포인터만큼 많은 비트이므로 long 값과 포인터 사이에 1 대 1 맵이 있습니다. 그러나 위반, 특히 두 번째 규칙의 위반은 드문 일이 아닙니다!

long(v)reinterpret_cast<long>(v)의 별명으로, 이는 보장되지 않습니다. ABI 사양에서 다르게 언급하지 않는 한 어떤 목적으로도 적합하지 않습니다.

그러나 어떤 이유로 든 코드를 작성한 사람은 누구나 int에서 long을 선호합니다. 그래서 그들은 다시 손가락을 가로 지르며, int에서 long 캐스팅에서 손실 될 수있는 비트에 필수 정보가 빠지지 않기를 바랍니다.

이 두 가지 용도는 고유 한 개체 식별자를 생성하거나 포인터에 의해 지원되지 않는 일종의 산술을 위해 포인터를 어떻게 든 포장하려고하는 것입니다.

  • 불투명 식별자는 void* 수 있으므로 일체형으로 캐스팅 할 필요가 없다.
  • ""형식의 차이를 얻기 위해 기본 포인터를 빼서 보통 "long"인 포인터에서 정수를 추출합니다 (예 : 나누기 연산).
+0

GUI 코드로 보았습니다. –

+2

악마에게 +1. – GManNickG

+0

악의를 나타내지 않을 수도 있습니다. 'void *'는 콜백에 함수를 통해 전달되는 불투명 한 사용자 데이터 항목 일 수 있습니다 (예 : 스레드 시작 데이터). 발신자에게 유연성을주는 것은'void * '입니다. 호출자는 정수 값을 전달할 수 있으며 통화 상대방에서 값을 빼낼 수 있습니다. Windows에서는 요즘 'ULONG_PTR' 사용자 데이터를 사용하여'long '으로 캐스트 할 필요가 없지만 int 형으로 변환해야합니다.이 경우에는 악은 아니지만 디자인이 아마도 더 나을 수 있습니다. –