5+253 如果 5 是 unsigned char, 253 是 unsigned char, 那加起來不就超過 char 的大小了嗎? 但是
cout << 5+300 << endl;
可以正常印出 258, 而不是被截掉的數值。
那這兩個數字 0x7fffffff 和 0xffff0000 是什麼 type 呢?
為什麼 0x7fffffff 不是 unsigned int?《linux c 編程 一站式學習》有答案, 我想驗證看看是不是真的, 其實應該讀 c spec, 但你知道的 ...
該怎麼驗證呢? 使用 c++ rtti, 以下程式碼使用 c++ rtti 來得到 type。
c++filt -t 可以把神秘的字母轉成看得懂的 type。
再來是一個很特別的數字, -2147483648。
測試環境是:
x86 32bit/linux
gcc 5.4.0
int: 32bit
longlong: 64bit
-2147483648 可以用 int 大小 (32bit) 裝下, 0x80000000 是其 16 進位表達式。
2147483648 卻要用 long long 大小 (64bit) 才能裝下, 0x0000000080000000 是其 16 進位表達式。
descent@debian64:ctrl_proc$ g++ -m32 -Wall -std=c++11 int.cpp -o int int.cpp: In function ‘int main(int, char**)’: int.cpp:12:29: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘long long int’ [-Wformat=] printf("%d\n", -2147483648); ^ int.cpp:10:7: warning: unused variable ‘i’ [-Wunused-variable] int i = -2147483648; ^ descent@debian64:ctrl_proc$ ./int |c++filt -t long long -2147483648
-2147483648 type 是 long long, 而不是 int, 雖然 int 裝的下 -2147483648, 怎麼回事, 從 AST 來看這個 printf("%d\n", -2147483648); 運算式。
main |int |func |global | func_body | printf __|___ | | %d\n - | 2147483648
-2147483648 被分成 -, 2147483648, 而 2147483648 是 long long type, 做了 - 運算後, 依然是 long long, 所以 -2147483648 是 long long, 也就是 0xffffffff80000000, 而 %d 預期是 int type, 所以編譯器便發出 warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘long long int’ [-Wformat=] 警告。
有趣的是 int.cpp L10, int i = -2147483648; 卻不會發警告, int i 是可以存進 -2147483648, 真奇怪, -2147483648 的 type 是 long long, 所以會有被截掉的可能, 但是由於 -2147483648 可以裝進 int, 所以不用擔心會被截掉。
《linux c 編程 一站式學習》作者很謹慎, 沒亂唬爛我。
c++ 是不是好用呢? 有一些高階語言的特性與低階語言的執行速度, 它是很了不起的語言。
ref:
Strange output of std::typeid::name()
沒有留言:
張貼留言
使用 google 的 reCAPTCHA 驗證碼, 總算可以輕鬆留言了。
我實在受不了 spam 了, 又不想讓大家的眼睛花掉, 只好放棄匿名留言。這是沒辦法中的辦法了。留言的朋友需要有 google 帳號。