簡體   English   中英

通過強制轉換為nullptr獲得成員變量的偏移量

[英]Getting the offset of a member variable via casting a nullptr

我正在查看<cstddef>的宏offsetof ,發現可能的實現是通過

#define my_offsetof(type, member) ((void*) &(((type*)nullptr)->member))

我嘗試過,確實可以按預期工作

#include <iostream>

#define my_offsetof(type, member) ((void*) &(((type*)nullptr)->member))

struct S
{
    char x;
    short y;
    int z;
};

int main()
{
    std::cout << my_offsetof(S, x) << '\n';
    std::cout << my_offsetof(S, y) << '\n';
    std::cout << my_offsetof(S, z) << '\n';

    S s;
    std::cout << (void*) &((&s)->x) << '\n'; // no more relative offsets
    std::cout << (void*) &((&s)->y) << '\n'; // no more relative offsets
    std::cout << (void*) &((&s)->z) << '\n'; // no more relative offsets
}

住在科利魯

我所做的唯一修改是,我使用最終強制轉換為void*而不是size_t ,因為我想將地址顯示為指針。

我的問題:

  1. 該代碼是否完全合法,即通過nullptr “訪問”成員然后獲取其地址是否合法? 如果是這樣,那么似乎&(((type*)nullptr)->member)計算成員相對於0的地址,確實是這種情況嗎? (看起來是這樣,在最后3行中,我獲得了相對於s地址的偏移量)。
  2. 如果我從宏定義中刪除對(void*)的最終轉換,則會出現段錯誤。 為什么? &(((type*)nullptr)->member)應該是type*類型的指針,還是在這里以某種方式刪除了類型?
  1. 該代碼完全合法嗎?

不, 這是未定義的行為 編譯器可以選擇以這種方式實現offsetof ,但這是因為它實現:它可以選擇如何實現自己的功能。 另一方面,您不會得到這種“奢華”。

您無法實現offsetof宏。 並非以任何符合標准的方式。

  1. 如果我從宏定義中刪除對(void *)的最終轉換,則會出現段錯誤。 為什么? &(((((type *)nullptr)-> member)不應該是type *類型的指針,還是在這里以某種方式刪除了類型?

嘗試打印my_offsetof(S, x)可能是一個段my_offsetof(S, x)因為xchar並且該表達式導致char* ),因為std::ostreamoperator<<將嘗試將char*打印為C樣式字符串

暫無
暫無

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

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