왜 / C의 타입 캐스팅에 'intptr_t'를 사용해야 하는가?
사용과 관련하여 질문이 있다.intptr_t
대long int
. 메모리 주소 증분(예: 수동 포인터 산술)은 데이터 유형에 따라 다르다는 것을 관찰했다.예를 들어, char 포인터를 증가시키면 메모리 주소에 1이 추가되는 반면, int 포인터를 증가시키면 4, 8, 긴 더블에 16이 추가되는 등...
처음에 나는 이런 일을 했다.
char myChar, *pChar;
float myFloat, *pFloat;
pChar = &myChar;
pFloat = &myFloat;
printf( "pChar: %d\n", ( int )pChar );
printf( "pFloat: %d\n", ( int )pFloat );
pChar++;
pFloat++;
printf( "and then after incrementing,:\n\n" );
printf( "pChar: %d\n", (int)pChar );
printf( "pFloat: %d\n", (int)pFloat );
잘 정리되고 실행되었지만 XCode는 나에게 "포인터에서 다른 크기의 정수까지"라는 타이프 캐스팅에 대한 경고를 주었다.
몇 번 구글링하고 빙빙 돌다가 (후자는 아직 단어인가?) 추천하는 사람도 있었다.intptr_t
:
#include <stdint.h>
...
printf( "pChar: %ld\n", ( intptr_t )pChar );
printf( "pFloat: %ld\n", ( intptr_t )pFloat );
그래서 오류가 해결됐군그래서, 나는, 지금부터, 나는, 내가 사용하는 것을 사용해야 한다고 생각했다.intptr_t
타이프 캐스팅 포인터의 경우...그러나 얼마간의 안절부절못한 끝에 나는 교체만 하면 문제를 해결할 수 있다는 것을 알게 되었다.int
와 함께long int
:
printf( "pChar: %ld\n", ( long int )pChar );
printf( "pFloat: %ld\n", ( long int )pFloat );
그래서 제 질문은, 왜 그럴까?intptr_t
유용하고, 언제 사용해야 하는가?이 경우 그것은 불필요해 보인다.확실히, 메모리 주소는myChar
그리고myFloat
너무 커서 몸에 맞지 않았다.int
... 그래서 그들을 타이프로 캐스팅했다.long int
s는 문제를 해결했다.
메모리 주소가 너무 커서long int
또한?지금 생각해 보면, 4GB 이상의 RAM이 있으면 가능할 것 같은데, 이 경우 메모리 주소는 2^32 - 1(서명되지 않은 긴 인트의 최대값...)을 초과할 수 있지만, C는 상상할 수 있는 것보다 훨씬 전에 생성되었지?아니면 그렇게 선견지명이 있었을까?
고마워!
intptr_t
64비트, 심지어 128비트 메모리 주소가 상상된 후에 만들어진 새로운 발명품이다.
포인터를 정수 유형에 캐스팅해야 하는 경우 항상 다음 중 하나를 사용하십시오.intptr_t
다른 어떤 것을 하는 것은 미래에 당신의 코드를 포팅해야 하는 사람들에게 불필요한 문제를 일으킬 것이다.
사람들이 64비트 Linux에서 컴파일하고 싶을 때 Mozilla/Firefox와 같은 프로그램에서 이것과 함께 모든 버그를 해결하는데 오랜 시간이 걸렸다.
중요한 건 어떤 플랫폼에서는int
사이즈는 맞지만 다른 쪽에선long
적당한 크기 입니다.어떤 것을 사용해야 하는지 어떻게 아십니까?넌 아냐.한 사람이 옳을 수도 있지만, 표준은 그것이 어느 것이 될 것인지에 대해 보증하지 않는다.따라서 표준은 어떤 플랫폼에 있든 상관없이 올바른 크기로 정의되는 유형을 제공한다.쓰기 전에 다음을 작성해야 하는 위치:
#ifdef PLATFORM_A
typedef long intptr;
#else
typedef int intptr;
#endif
이제 당신은 다음과 같이 쓰십시오.
#include <stdint.h>
그리고 그것은 훨씬 더 많은 사건들을 다루고 있다.코드가 실행되는 모든 플랫폼에 대해 위의 코드 조각을 전문으로 한다고 상상해 보십시오.
당신은 당신의 삶을 더 쉽게 만들 수 있다.p
변환 지정자:
printf("%p\n", (void *)foo);
또한 유형 변수를 인쇄할 수 있는 휴대용 방법(u)intptr_t
는 것을 사용하는 것이다.PRI*PTR
로부터의 매크로.inttypes.h
; 다다은 사사다.p
내 플랫폼(32비트):
printf("%08" PRIxPTR "\n", (uintptr_t)(void *)foo);
은 다음과 같이 .void *
완전한 휴대성을 위해 필요하지만, 동일한 포인터 표현을 가진 플랫폼에서 생략할 수 있다.
먼저intptr_t
데이터 포인터(함수가 아님) 전용이며, 존재한다고 보장되지 않는다.
그렇다면, 아니, 인쇄를 목적으로 사용해서는 안 된다.그%p
그걸 위한 거야넌 그냥 에 포인터를 던지면 돼(void*)
여기 있어.
그것은 또한 산술/개별 바이트에 접근하는 데도 좋지 않다.캐스팅(unsigned char*)
대신에
intptr_t
포인터를 정수로 해석해야 하는 드문 경우를 위한 것이다.그렇게 하지 않으면 안 된다.
참조URL: https://stackoverflow.com/questions/6326338/why-when-to-use-intptr-t-for-type-casting-in-c
'IT이야기' 카테고리의 다른 글
(void) 0이 C와 C++에서 작동하지 않는 이유는? (0) | 2022.05.21 |
---|---|
Vue에서 이벤트 버스 및 Vuex 사용 (0) | 2022.05.21 |
~asset 폴더의 Vue + Webpack 별칭 동적 이미지 src (0) | 2022.05.21 |
중단 문과 계속 문 사이의 차이 (0) | 2022.05.21 |
공리를 부르는 곳.Vue.js 앱에서 사용되는 인터셉터.request.use? (0) | 2022.05.21 |