2012-01-10 3 views
1

0x88과 같은 리터럴이 signed int으로 캐스팅 될 것이라고 생각했습니다. 그러나 다음 프로그램의 산출물은 나의 초기 가정과는 다르다. 누군가가 이것에 대해 밝히고 무슨 일이 일어 났는지 설명해 주시겠습니까? 내 가정이 정확하면C++에서 0x88 리터럴 캐스팅은 무엇입니까?

printf("%hd, %hu\n", 0x88); // output: 136 (10001000), 65416 (11111111 10001000) 

0x88 먼저 signed int에 캐스트 할 것이며이 될 :

%hd로 인쇄 할 때, 그것은 signed short에 캐스트 할 것
00000000 00000000 00000000 10001000 

산출되는 :

00000000 10001000 

을 입력하고 %hd으로 출력하면 unsigned short이됩니다. 다시 y ields이 : 실수로 잃어버린 printf의 매개 변수 중 하나

00000000 10001000 

나는 모두 printf의의 출력이 136

갱신 될 것으로 예상. 당신들이 지적한대로해야합니다 :

printf("%hd, %hu\n", 0x88, 0x88); 
+8

의 printf'의 인수 목록()'에 또 다른'0x88'를 넣습니다. 나는 당신이 단순히 정의되지 않은 행동을보고 있다고 생각합니다. –

+0

나는 이것이 곧 갈색 종이 봉투 질문이 될 것이라고 예측한다. :-) –

+0

OK - 물어볼 것입니다 - "갈색 종이 봉투 질문"은 무엇입니까? –

답변

5

C++에서 모든 리터럴은 "캐스팅 대상"이 아닙니다. 추가 접미어가없는 정수 리터럴 유형은 값을 나타 내기에 충분히 작은 가장 작은 정수이지만 int보다 작지는 않습니다.

따라서 0x88의 유형은 int입니다.

같은, 당신의 printf은 다음과 같아야합니다

printf("%d",0x88); 

하는 것으로 :이 매개 변수보다 더 많은 형식 지정자를 가지고로 printf("%hd, %hu\n", 0x88);

  • 가 UB를 호출한다.
  • 매개 변수와 다른 형식 지정자를 사용하면 캐스트가 수행되지 않으며 최악의 경우 UB도 호출됩니다. 따라서 short int에 형식 지정자 %hd을 사용하려면 인수 유형도 동일해야합니다.
+0

예. 즉, 대다수의 컴파일러는 % hd에 대한 인수가 짧은 int가 아닌지 신경 쓰지 않습니다. 구현은 int의 경우와 같습니다. (즉, 대부분의 32 비트 시스템은 짧은 int 인 경우에도 4 바이트를 푸시합니다.) –

+0

@MrLister : 엄밀히 말하면, 여전히 UB를 호출합니다. 오늘날 사람들이 사용하는 구현 및 아키텍처의 수가 증가하고있는 것 같습니다. 64 비트 데스크톱, 태블릿, 스마트 폰, TV, 미디어 장치, GPU 등에서 C 또는 C++로 프로그래밍하는 사람들이 점점 많아지고 있습니다.이 모든 것이 모두 드문 "일반적인"아키텍처입니다. 이 경우처럼 쉬울 때, 바로 시작해야합니다. 이미 빅 엔디안 아키텍처에서이 작업이 실패 할 수도 있고, 이국적 일 필요도 없습니다. – PlasmaHH

+1

나는 그것이 UB인지 모르겠습니다. 'printf'와 같은 vararg 함수에'short'를 실제로 전달할 수 없습니다. 자동적으로'int'로 승격됩니다. http://stackoverflow.com/questions/2875670/is-there-any-way-to-retrieve-a-float-from-a-varargs-functions-parameters – MSalters

0

variadic 기능에주의하십시오. printf에는 지정자가있는만큼 많은 인수 (더하기 형식 자체)가 필요하며 여기에는 2 개의 지정자가 있지만 형식을 지정하는 인수는 하나뿐입니다.

당신이 사용하는 경우 correct line :

#include <cstdio> 

int main() { 
    std::printf("%hd, %hu\n", 0x88, 0x88); 
} 

당신은 볼 수 있습니다 :

136, 136 
+0

궁금한 점이 있으시면 플랫폼에 ' short int'는'int'와 같은 크기입니까? –

+0

@Let_Me_Be : no (http://ideone.com/VHevy 참조), 그래서'int'의 두 바이트 만 출력 될 것으로 예상됩니다. 그리고 그것은 아마도 작은 엔디안 기계 일 것입니다. –

+0

variadric 함수를 사용하면 제대로 작동합니까? 모든 매개 변수를 4 바이트로 정렬합니까? –