[英]Promotions and conversions of variables in printf()
在這種情況下,
#include <stdio.h>
int main()
{
unsigned char a = 1;
printf("%hhu", -a);
return 0;
}
printf 中的參數-a
通過一元減號運算符的printf
提升提升為int
,隨后通過默認參數提升提升,最后通過格式說明符轉換為unsigned char
。
所以-a
=> -(int)a
(by ~
) => function call => (unsigned char)-(int)a
(by %hhu
) 沒有轉換。 我的想法對嗎?
你是正確的a
在-a
中被提升為int
,並且printf("%hhu", -a);
將int
傳遞給printf
。 使用%hhu
執行的名義轉換不清楚。
請注意,如果a
不為零,則-a
會生成一個不是unsigned char
值的值(在int
中)。 此外,對於二進制補碼 8 位有signed char
,如果a
大於 128,則-a
生成一個不是有signed char
值的值。
要了解%hhu
,我們查看 C 2018 7.21.6.1 8 中u
的規范:
unsigned int
參數轉換為無符號八進制 (o)、無符號十進制 (u)、...
對於 7.21.6.1 7 中的hh
:
指定后面的 d、i、o、u、x 或 X 轉換說明符適用於有
signed char
或unsigned char
參數(該參數將根據 integer 提升,但其值應轉換為有signed char
或打印前的unsigned char
);…
首先我們要解決“ signed char
or unsigned char
”這個問題。 這是否表示我們可以為%hhu
傳遞一個有signed char
或unsigned char
? 我想不是; 我認為作者剛剛將%hhd
(用於轉換有signed char
)和%hhu
(用於轉換unsigned char
)的語言放在一起。 所以我相信目的是應該為%hhu
轉換規范傳遞一個提升的unsigned char
。
Apple Clang 11.0.0 似乎同意,當傳遞-a
(但不是a
)時,它警告:“警告:格式指定類型'unsigned char'但參數的類型為'int' [-Wformat]”
如上所述,傳遞-a
可能傳遞的值不能由傳遞提升的unsigned char
產生。 它甚至可以傳遞一個不能通過傳遞提升的有signed char
或unsigned char
而產生的值。 在這種情況下,可以說我們違反了傳遞unsigned char
的要求,因此 C 標准沒有指定結果行為。 盡管它說傳遞的值應轉換為unsigned char
,但我認為這是一種名義上的轉換,而不是對庫實現的特定要求,這也屬於“好像”規則:它實際上沒有如果程序的結果定義行為相同,則執行。 但是,由於可能未定義傳遞不正確的值,因此我們沒有定義的行為。
這可能是對規則的嚴格閱讀,但如果printf
在a
為 1 時打印“4294967295”而不是“255”,我不會感到驚訝。
printf
是可變參數 function。 ...
參數傳遞的 arguments 的類型在 function 內部未知。 因此,任何可變參數 function 必須依賴其他機制來解釋va_arg
的 arguments 的類型。 printf
和家人使用const char* format
字符串“告訴他們”通過了哪種 arguments。 傳遞與其格式說明符指定的預期類型不同的類型會導致未定義的行為。
例如:
printf("%f", 24)
是未定義的行為。 在任何地方都沒有從int
到float
的轉換,因為 arguments 按原樣傳遞(在提升之后),並且在printf
內部 function 錯誤地將其第一個參數視為float
。 printf
不知道也無法知道參數的真實類型是int
。
Variadic arguments 進行了一些自己的促銷活動。 對您的問題感興趣的unsigned char
被提升為int
或unsigned int
(我不確定 tbo)。 因此,可變參數實際上無法為unsigned char
類型。 所以hhu
雖然確實是unsigned char
的說明符,但它實際上會期望一個unsigned int
( int
),這就是你傳遞給它的內容。
所以 afaik 代碼是安全的,因為由一元減號和傳遞可變參數 arguments 引起的兩個 integer 促銷活動。 不過,我不是 100% 確定。 Integer 促銷活動詭異而復雜。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.