2016-09-10 2 views
1

코드 :왜 캐스트 후에 포인터의 값이 변경됩니까?

int main(void) { 
register int rsp asm("rsp"); 
int temp=rsp; 

printf("\n (rsp)%p \n", rsp); 
printf("\n (temp)%p \n", temp); 
printf("\n (void*)(rsp)%p \n", (void*)rsp); 
printf("\n (void*)(temp)%p \n", (void*)temp); 

return 0; 
} 

출력 :

(rsp)0xffffcbe0 

(temp)0xffffcbe0 

(void*)(rsp)0xffffffffffffcbe0 

(void*)(temp)0xffffffffffffcbe0 

난이 바보 같은 질문이다 생각하지만, 왜 주조 후 포인터 변경의 가치는 무엇입니까? 다른 유형으로 캐스트하려고했는데 항상 같은 오프셋을 얻습니다. 감사합니다.

+0

32 비트 INT 비트 및 64 비트 포인터는, 아마도 – 4386427

+2

나는 UB – 4386427

+0

원인 printf' 처음 두가'당신은 rsp''의 값을 인쇄하고'temp' 사용하여 '%의 p'하고 확실 해요 하지만 그들은 포인터가 아닙니다. 그러므로 네 개의 모든 printf는 정의되지 않은 동작을합니다. 그들의 주소를 대신 출력하십시오 ('& rsp','& temp' 등). – Peter

답변

2

왜 캐스팅 후에 포인터 값이 변경됩니까?

intrspint하지 포인터.

"%p"을 사용하면 int으로 정의되지 않은 동작이 발생합니다.

unsigned으로 변환 된 값은 OP에 의해 인쇄 된 것으로 가정합니다. 코드가 register int rsp asm("rsp"); 같이 int에 대한 포인터를 띤다 때

printf("\n (rsp)0x%x \n", (unsigned) rsp); // (rsp)0xffffcbe0 
printf("\n (temp)0x%x \n", (unsigned) temp); // (temp)0xffffcbe0 

, 그것은 의미 @David Wohlferd을 잃을 수 있습니다. int을 포인터로 변환 할 때 좁은 숫자 인 int을 처리하기 위해 부호 확장과 같은 다양한 변환 메커니즘이 발생합니다. "%p"에는 구현 특정 형식이 있습니다.

명확해야 : OP 코드가 원래 asm("rsp")의 주소를 확실히 인쇄하지 않습니다. (컴파일러 특정 확장).

C는 동등한 정수 및 개체 포인터와의 변환을 제공하는 선택적 정수 유형 (u)intptr_t을 제공합니다. 개체 포인터를 정수로 저장하려면 해당 형식을 사용하십시오. 불행하게도, C는 비 void* 포인터와 (u)intptr_t 값을 인쇄하기위한 래치 인쇄 지정자가 없으므로 다음과 같이 캐스팅됩니다.

#include <stdint.h> 
#include <stdio.h> 

char *s = "rsp"; 
printf("pointer %p\n", (void *) s); 

uintptr_t i_ptr = (uintptr_t) s; 
printf("integer 0x%jX\n", (uintmax_t) i_ptr); 
+0

감사합니다. –

관련 문제