簡體   English   中英

使用 INTXX_C 宏和執行類型轉換為文字有什么區別?

[英]What is the difference between using INTXX_C macros and performing type cast to literals?

例如,這段代碼被破壞了(我剛剛在實際代碼中修復了它......)。

uint64_t a = 1 << 60

它可以固定為,

uint64_t a = (uint64_t)1 << 60

但后來這通過了我的大腦。

uint64_t a = UINT64_C(1) << 60

我知道UINT64_C(1)是一個在 64 位系統中通常擴展為1ul的宏,但是它與僅僅進行類型轉換有什么不同呢?

(uint64_t)1形式上是轉換為uint64_tint1
1ulunsigned long類型的常量1 ,它可能與 64 位系統上的uint64_t相同。
宏是為uint64_t類型的常量(文字)指定正確后綴的可移植方式。

當您處理常量時,所有計算都將由編譯器完成,結果是相同的。

宏附加的后綴( ul ,系統特定)只能用於文字常量。

(uint64_t)可用於常量和變量值。 使用常量,它將具有與后綴/宏相同的效果,使用不同類型的變量,它可以執行值的截斷或擴展,例如,當從 32 位更改為 64 位時,用 0 填充高位。

如果您使用UINT64_C(1)(uint64_t)1 ,這是一個品味問題。 宏使您更清楚地知道您正在處理一個常量。

沒有明顯的區別或優勢,這些宏有點多余。 演員表和宏之間有一些細微的差別:

  • (uintn_t)1用於預處理器目的可能很麻煩,而UINTN_C(1)擴展為單個 pp 令牌。

  • UINTN_C的結果類型實際上是uint_leastn_t而不是uintn_t 所以它不一定是你期望的類型。

  • 如果您在代碼中鍵入1而不是1u ,則用於 MISRA-C 等編碼標准的 Static 分析器可能會抱怨,因為無論大小如何,移動有符號整數都不是一個好主意。
    (uint64_t)1u符合 MISRA, UINT64_c(1)可能不符合,或者至少分析器無法分辨,因為它無法像編譯器那樣擴展 pp 令牌。 而且UINT64_C(1u)可能不起作用,因為這個宏實現可能看起來像這樣:

     #define UINT64_C(n) ((uint_least64_t) n ## ull) // BAD: 1u##ull = 1uull

一般來說,我建議使用顯式強制轉換。 或者更好地將所有這些包裝在一個命名常量中:

#define MY_BIT ( (uint64_t)1u << 60 )

UINT64_C(1)通過令牌粘貼生成單個令牌,而((uint64_t)1)是具有相同值的常量表達式。

它們可以在發布的示例代碼中互換使用,但不能在預處理器指令(如#if表達式)中使用。

XXX_C宏應用於定義可在#if表達式中使用的常量。 僅當常量必須具有特定類型時才需要它們,否則只需將常量拼寫為沒有后綴的十進制或十六進制就足夠了。

暫無
暫無

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

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