intptr_t
和uintptr_t
的字符串格式對32位和64位體系結構都有效。intptr_t和uintptr_t的字符串格式
編輯
warning: format ‘%x’ expects type ‘unsigned int’, but argument 2 has type "AAA"
這是我在64位,但不是在32位得到警告。
intptr_t AAA
intptr_t
和uintptr_t
的字符串格式對32位和64位體系結構都有效。intptr_t和uintptr_t的字符串格式
編輯
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
我編譯一些代碼的環境這對於一些原因是不是有PRI.PTR
宏定義在inttypes.h
中,其中intptr_t
定義爲32位中的int
和64位中的long int
。
我通過使用%li
格式說明符並在printf
參數中將變量轉換爲long int
來破解警告。這是安全的在這個環境內,因爲如上所述intptr_t
永遠不會比long int
更長。
如果您可以避免使用此解決方案,我不建議使用此解決方案,但至少可以解決警告。
%p
應該作爲%x
的替代品,因爲uintptr_t
被定義爲與平臺上的指針大小相同的無符號整數。
編輯:不幸的是,至少在我的編譯器中,你必須將變量轉換爲(void *)。但是,我認爲將uintptr_t強制轉換爲指針是安全的。
非常不正確。 – 2017-10-31 17:07:48
我認爲,即使long int
是不安全的,你應該嘗試long long int
,必須存在,因爲你正在處理的64位架構,你有intptr_t
了。
在某些64位架構(我認爲微軟的Windows會如此),long int
可以保持在32位的寬度,以滿足MS-DOS時代的假設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. S. %p
在這種情況下可能不會很好,因爲%p
可能會在十六進制之前打印裸字0x
和/或可能會打印零填充值。例如,如果應用了這兩者,則代碼printf("%p\n", (void*)16);
將在32位平臺上打印0x00000010
,在64位平臺上打印0x0000000000000010
;應該打印海報應該只有10
。
####################################### 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;
}
抱歉,這個問題用C標記,爲什麼用cpp解決方案回答? – Stargateur 2017-10-31 07:21:53
使用'#include
@Stargateur你說這是一個cpp解決方案,只是因爲有一個cpp後綴? – 2017-10-31 07:41:10
使用示例:'uinptr_t p = SOME_VALUE; \ n「,p);' – 2011-04-26 20:33:17
感謝您的回答,我的問題可能並非如此精確......我究竟想知道是否有像*這樣的強大格式, *「%d」**爲整數等。我得到一些警告,取決於硬件架構。我編輯了我的問題。 – thetna 2011-04-26 20:33:40