簡體   English   中英

printf()中變量的提升和轉換

[英]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 charunsigned char參數(該參數將根據 integer 提升,但其值應轉換為有signed char或打印前的unsigned char );…

首先我們要解決“ signed char or unsigned char ”這個問題。 這是否表示我們可以為%hhu傳遞一個有signed charunsigned 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 charunsigned char而產生的值。 在這種情況下,可以說我們違反了傳遞unsigned char的要求,因此 C 標准沒有指定結果行為。 盡管它說傳遞的值應轉換為unsigned char ,但我認為這是一種名義上的轉換,而不是對庫實現的特定要求,這也屬於“好像”規則:它實際上沒有如果程序的結果定義行為相同,則執行。 但是,由於可能未定義傳遞不正確的值,因此我們沒有定義的行為。

這可能是對規則的嚴格閱讀,但如果printfa為 1 時打印“4294967295”而不是“255”,我不會感到驚訝。

printf是可變參數 function。 ...參數傳遞的 arguments 的類型在 function 內部未知。 因此,任何可變參數 function 必須依賴其他機制來解釋va_arg的 arguments 的類型。 printf和家人使用const char* format字符串“告訴他們”通過了哪種 arguments。 傳遞與其格式說明符指定的預期類型不同的類型會導致未定義的行為。

例如:

printf("%f", 24)

是未定義的行為。 在任何地方都沒有從intfloat的轉換,因為 arguments 按原樣傳遞(在提升之后),並且在printf內部 function 錯誤地將其第一個參數視為float printf不知道也無法知道參數的真實類型是int

Variadic arguments 進行了一些自己的促銷活動。 對您的問題感興趣的unsigned char被提升為intunsigned int (我不確定 tbo)。 因此,可變參數實際上無法為unsigned char類型。 所以hhu雖然確實是unsigned char的說明符,但它實際上會期望一個unsigned int ( int ),這就是你傳遞給它的內容。

所以 afaik 代碼是安全的,因為由一元減號和傳遞可變參數 arguments 引起的兩個 integer 促銷活動。 不過,我不是 100% 確定。 Integer 促銷活動詭異而復雜。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM