intptr_t 및 uninttr_t의 문자열 형식
의 문자열 형식은 무엇입니까?intptr_t
그리고. uintptr_t
이는 32비트 및 64비트 아키텍처 모두에 유효합니다.
편집
warning: format ‘%x’ expects type ‘unsigned int’, but argument 2 has type "AAA"
이것은 제가 64비트에서 받고 있는 경고이지만 32비트에서는 받지 않습니다.
intptr_t AAA
그것은 다음의 매크로일 것입니다.inttypes.h
:
위해서printf
:PRIdPTR PRIiPTR PRIoPTR PRIuPTR PRIxPTR PRIXPTR
위해서scanf
:SCNdPTR SCNiPTR SCNoPTR SCNuPTR SCNxPTR
사용 예:
uintptr_t p = SOME_VALUE;
printf("Here's a pointer for you: %" PRIxPTR "\n", p);
저는 당신이 'z' 수식어를 사용하는 것을 고려해야 한다고 생각합니다.이렇게 하면 size_togsize_t에 해당하는 모든 것이 변환되며, (u)inttr_t에서도 작동한다는 것을 알게 되었습니다.
예:
intptr_tip = ...printf("ip = %zd\n", ip);
%p
의 대체품으로 작동해야 합니다.%x
,부터uintptr_t
플랫폼의 포인터와 같은 크기의 부호 없는 정수로 정의됩니다.
편집: 불행히도 적어도 내 컴파일러에서는 변수를 (void *)에 캐스팅해야 합니다.하지만 포인터에 uinttr_t를 캐스트하는 것이 안전하다고 생각합니다.
####################################### CPP type proving code (identifying type by typeid)
$ cat typeid.cpp
#include <stdio.h>
#include <stddef.h>
#include <stdint.h>
#include <time.h>
#include <typeinfo>
#define name(t) printf("%30s : %s\n", #t, typeid(t).name())
// g++|clang++ -o ./typeid.exe typeid.cpp -m32 && ./typeid.exe
// g++|clang++ -o ./typeid.exe typeid.cpp -m64 && ./typeid.exe
int main(int argc, char* argv[]) {
name(ptrdiff_t);
name(intptr_t);
name(uintptr_t);
return 0;
}
####################################### C type proving code (identifying type by _Generic)
$ cat typeid.c
#include <stdio.h>
#include <stdint.h>
#include <stddef.h>
#include <time.h>
/* matches the type name of an expression */
#define name_match(e) _Generic((e), \
_Bool: "_Bool", \
char: "char", \
signed char: "signed char", \
unsigned char: "unsigned char", \
short: "short", \
unsigned short: "unsigned short", \
int: "int", \
unsigned int: "unsigned int", \
long: "long", \
unsigned long: "unsigned long", \
long long: "long long", \
unsigned long long: "unsigned long long", \
float: "float", \
double: "double", \
long double: "long double", \
default: "unknown")
#define name(t, e) printf("%30s : %s\n", #t, name_match(e))
int main() {
ptrdiff_t ptrdiff_v = 0;
intptr_t intptr_v = 0;
uintptr_t uintptr_v = 0;
name(ptrdiff_t, ptrdiff_v);
name(intptr_t, intptr_v);
name(uintptr_t, uintptr_v);
}
####################################### run in arch32
$ clang++ -o ./typeid.exe typeid.cpp -m32 && ./typeid.exe
ptrdiff_t : i
intptr_t : i
uintptr_t : j
$ clang -o ./typeid.exe typeid.c -m32 && ./typeid.exe
ptrdiff_t : int
intptr_t : int
uintptr_t : unsigned int
result:
intptr_t == ptrdiff_t
uintptr_t == unsigned ptrdiff_t
####################################### run in arch64
$ clang++ -o ./typeid.exe typeid.cpp -m64 && ./typeid.exe
ptrdiff_t : l
intptr_t : l
uintptr_t : m
$ clang -o ./typeid.exe typeid.c -m64 && ./typeid.exe
ptrdiff_t : long
intptr_t : long
uintptr_t : unsigned long
result:
intptr_t == ptrdiff_t
uintptr_t == unsigned ptrdiff_t
####################################### man 3 printf
t -- A following integer conversion corresponds to a ptrdiff_t argument.
####################################### conclusion
// intptr_t == ptrdiff_t
// uintptr_t == unsigned ptrdiff_t
// so:
// 1) intptr_t has string format %td
// 2) uintptr_t has string format %tu
#include <stdio.h>
#include <stdint.h>
int main(int argc, char *argv[]) {
intptr_t x = 0;
uintptr_t y = 0;
scanf("%td %tu", &x, &y);
printf("out: %td %tu\n", x, y);
return 0;
}
나는 어떤 이유에서인지 없는 환경에서 코드를 컴파일하고 있습니다.PRI.PTR
정의된 매크로inttypes.h
그리고 그 안에서intptr_t
로 정의됩니다.int
32비트로long int
64비트로.
나는 사용하여 경고를 해킹했습니다.%li
형식 지정자 및 변수 캐스팅 대상long int
에서printf
매개 변수이 환경에서는 안전합니다. 왜냐하면intptr_t
절대 a보다 길 수 없습니다.long int
상술한 바와 같이
피할 수 있다면 이 솔루션을 사용하는 것을 권장하지는 않지만, 적어도 경고는 해결되었습니다.
내 생각엔 심지어long int
안전하지 않습니다, 그리고 당신은 노력해야 합니다.long long int
64비트 아키텍처에서 작업 중이고 현재 사용 중이기 때문에 존재해야 합니다.intptr_t
이미.
일부 64비트 아키텍처(Microsoft Windows도 그럴 것으로 생각됨)에서는long int
MS-DOS 시대의 가정을 만족시키기 위해 32비트 폭으로 유지할 수 있습니다.short int
항상 16비트이며long int
는 항상 32비트입니다.
32비트 플랫폼에서도long int
,printf("%llx", (unsigned long long)AAA);
효과가 있을 것입니다.그리고 당신은 더 선호하는 형태를 고려해야 합니다.printf("%jx", (uintmax_t)AAA);
가능하면.
일부 오래된 컴파일러의 경우 사용해야 할 수 있습니다."%Lx"
(GNU C의 경우, 캐스팅 포함)unsigned long long
) 또는"%I64x"
(Visual C++의 경우, 캐스팅 포함)__uint64
)(64비트 정수의 경우).
추신.%p
이 경우에는 좋지 않을 수 있습니다, 왜냐하면%p
맨 단어를 인쇄할 수 있습니다.0x
16진수 앞에 표시하거나 0-숫자 값을 인쇄할 수 있습니다.둘 다 적용되는 경우, 예를 들어 코드는printf("%p\n", (void*)16);
인쇄 예정0x00000010
32비트 플랫폼 및0x0000000000000010
64비트 플랫폼에서; 포스터는 그저 바라야 했습니다.10
언급URL : https://stackoverflow.com/questions/5795978/string-format-for-intptr-t-and-uintptr-t
'programing' 카테고리의 다른 글
mysql - IF 문 내에서 코드 블록을 실행하는 방법(프로시저에서는 실행하지 않음) (0) | 2023.08.29 |
---|---|
요소가 부모의 자식인지 확인 (0) | 2023.08.29 |
잘못된 요청 활동 결과 코드 입력 (0) | 2023.08.29 |
CSS 필터를 배경 이미지에 적용하는 방법 (0) | 2023.08.29 |
PowerShell 패키지 관리, 패키지 공급자를 제거하는 방법은 무엇입니까? (0) | 2023.08.29 |