簡體   English   中英

Typedef和printf格式說明符

[英]Typedefs and printf format specifiers

typedef的一個常見用途是使變量的“類型”能夠更好地了解變量的用途,而無需重新定義其后面的存儲結構。

但是,我也看到typedef是一種改變一類變量的存儲結構的方法。

例如,如果我定義

typedef uint32_t my_offset_t

並且具有my_offset_t類型的my_offset_t ,將代碼庫從uint32_t切換到charuint64_t就像更改一行並重新編譯一樣簡單(假設我使用的是sizeof而不是硬編碼的大小), 除了printf /的情況scanf

有沒有辦法根據類型以一種簡單的方式交換格式說明符,沒有printf / scanf ,if-elses或ifdefs的包裝函數?

謝謝!

對於任何感興趣的人,我正在修改一個使用16位偏移來處理32位偏移的LKM,但是如果需要的話,希望能夠以最小的變化進行64位(或其他!)偏移。

這是一項棘手的業務,但C99及后來的<inttypes.h>顯示了這樣做的方法。

對於每個定義的類型,您需要為自己提供一組適當的'PRI'和'SCN'宏,小心避免使用標准化的命名空間。

例如,您可以將XYZ用作項目特定的前綴,並生成:

XYZ_PRIx_my_offset_t
XYZ_PRId_my_offset_t
XYZ_PRIX_my_offset_t
XYZ_PRIu_my_offset_t
XYZ_PRIo_my_offset_t

和SCN等價物。 此外,您可以根據基類型的等效宏來定義它們,因此:

#define XYZ_PRIx_my_offset_t PRIx32
#define XYZ_PRId_my_offset_t PRId32
#define XYZ_PRIX_my_offset_t PRIX32
#define XYZ_PRIu_my_offset_t PRIu32
#define XYZ_PRIo_my_offset_t PRIo32

在您的代碼中,使用XYZ_PRIx_my_offset_t宏構建格式字符串:

printf("Offset: 0x%.8" XYZ_PRIX_my_offset_t "\n", my_offset_value);

如果您隨后需要將所有內容更改為64位,則可以適當地編輯typedef和宏定義,其余代碼保持“不變”。 如果你真的很小心,你可以非常接近完全不變。

確保在設置了大量警告的32位和64位系統上進行編譯。 GCC不會對您當前平台上的非問題發出警告,但它們可能會出現在另一個平台上。 (我剛剛修復了一些在64位上干凈但在32位上不干凈的代碼;它現在使用像XYZ_PRId_int4這樣的宏而不是%d並在兩者上干凈地編譯。)

如果您查看我之前關於inttypes.h的問題,您可以看到系統定義的格式說明符如何與typedef(通過#define )一起使用,以便為您的自定義類型創建自定義打印說明符。

另一種解決方案是轉換和從intmax_t有符號類型和uintmax_t的無符號類型。 例如:

printf("%ju\n", (uintmax_t)n);

如果n是任何無符號類型,則將正常工作。

對於*scanf()函數,您必須讀入臨時對象然后分配。

(這假設您的運行時庫支持這些功能。)

暫無
暫無

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

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