簡體   English   中英

這個C代碼塊如何解析為整數分配?

[英]How does this C code-block get resolved to an integer assignment?

好的,在編寫C代碼的15年中,我從未見過這樣的代碼,而且我也不知道它是如何工作的。 它以某些C99代碼為中心,其中多行代碼被解析為整數值。 它來自libplist,特別是這里 好的,它從第394行開始,在該行中,結構的uint64_t成員被分配了宏UINT_TO_HOST的結果

data->intval = UINT_TO_HOST(&data->intval, size);

UINT_TO_HOST是一個宏,它使用一個指向無符號整數的指針,該整數的大小以btes為單位。 宏定義了到一組不同uint大小的指針的並集,然后將地址設置為傳遞給宏的uint指針。 然后,它會繼續對齊內存中的uint,以便正確地與另一個宏進行字節交換。 UINT_TO_HOST在第172行中定義

#define UINT_TO_HOST(x, n) \
({ \
    union plist_uint_ptr __up; \
    __up.src = x; \
    (n == 8 ? be64toh( get_unaligned(__up.u64ptr) ) : \
    (n == 4 ? be32toh( get_unaligned(__up.u32ptr) ) : \
    (n == 3 ? uint24_from_be( __up ) : \
    (n == 2 ? be16toh( get_unaligned(__up.u16ptr) ) : \
    *__up.u8ptr )))); \
})

get unaligned使用結構和gcc屬性打包的技巧,該屬性將根據類型返回在內存中對齊的指針值。

  #define get_unaligned(ptr)              \
  ({                                              \
    struct __attribute__((packed)) {          \
      typeof(*(ptr)) __v;             \
    } *__p = (void *) (ptr);              \
    __p->__v;                     \
  })

be64toh只是做一些適當的遮罩和移位。

#define be64toh(x) ((((x) & 0xFF00000000000000ull) >> 56) \
                | (((x) & 0x00FF000000000000ull) >> 40) \
                | (((x) & 0x0000FF0000000000ull) >> 24) \
                | (((x) & 0x000000FF00000000ull) >> 8) \
                | (((x) & 0x00000000FF000000ull) << 8) \
                | (((x) & 0x0000000000FF0000ull) << 24) \
                | (((x) & 0x000000000000FF00ull) << 40) \
                | (((x) & 0x00000000000000FFull) << 56)) 

問題是UINT_TO_HOST實際上如何將值返回到data-> intval中,因為UINT_TO_HOST基本上被解析為一組花括號{}中的3行代碼。 同樣的事情似乎發生在get_unaligned內部,大概是最后一條語句

__P - > _ V;

是什么得到回報。 這個功能叫什么,任何人都可以指向該“功能”的一些文檔嗎?

這稱為語句表達式,它是GNU擴展。 這是您可能需要閱讀一些文檔。

正如其他人指出的那樣,宏使用GCC語法“表達式中的語句”。

但是宏本身的格式不正確。 小心點。 宏的代碼可能會被破壞,因為里面存在{ }
例如:

union plist_uint_ptr __up;
__up.src = 3;
UINT_TO_HOST(__up.src, 8);

宏擴展后,將獲得以下語句: __up.src = __up.src; 只能給出一個垃圾值,因為在宏的塊作用域中再次定義了對象__up

最近在這里討論了這種麻煩(第1部分的第一部分,然后跳到第5部分):

使用C中的宏可以創建多少個偽函數?

問題在於內部變量__up隱藏了外部變量__up的值,並且該宏無法按預期工作。
因此,它是不可重用的代碼。

暫無
暫無

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

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