0

Minimal code reproducible code:

struct Struct
{
    int value;
    int* a;
};

template <typename T>
void Print(T value)
{
    int size = sizeof(value);
    printf("%d %d\n", value, size);
}

int main()
{
    auto aAddress = &Struct::a;
    Print(aAddress);
    return 0;
}

In function main(), I take the address of a non-static field a through Struct type name without instantiating it. A few questions:

  1. What is the resulting type of aAddress? Clang and GCC both reports its size to be sizeof(void*) (4 bytes when compiled to 32-bit code, and 8 bytes when compiled to 64-bit code), whereas MSVC reports its size to be 4 bytes no matter whether you compile code as 32-bit or 64-bit.
  2. What is the value of aAddress supposed to be? On all three compilers (Clang, GCC, MSVC) it seems to be equal to offsetof(Struct, a). Is this a mere coincidence (and the actual result is undefined) or is it indeed equal to offset of that field from the beginning of the struct?
Sunius
  • 2,789
  • 18
  • 30
  • Did you try using a debugger? Debuggers should be able to show you the type of a particular object. – Sam Varshavchik Nov 15 '20 at 00:00
  • I did... Visual Studio debugger seems to think that the type is `int**` which makes no sense on 64-bit since its size is not 8. – Sunius Nov 15 '20 at 00:02
  • 4
    https://en.cppreference.com/w/cpp/language/pointer - see pointer to data member – Mat Nov 15 '20 at 00:03
  • `&Struct::a` is of type `int Struct::*` (a pointer to an `int` member of `Struct`). It is implementation-defined what `sizeof` yields for that type - nothing preventsit from being equal to `sizeof(void *)` and no rule prevents it being non-equal. If `o` is an instance of `Struct`, then `o.*aAddress` in your code accesses `o.a`. – Peter Nov 15 '20 at 00:08
  • please one question per question. – 463035818_is_not_an_ai Nov 15 '20 at 00:08
  • `printf("%d %d\n", value, size);` This is wrong in general, and will actually fail if either or both arguments are wider than an `int`. – dxiv Nov 15 '20 at 00:09
  • pointers to members is an abstraction. The standard specifies what you can do with such pointer, how it is implemented is implementation details. You can think of it as an offset with respect to the adress of an object yes – 463035818_is_not_an_ai Nov 15 '20 at 00:11
  • 1
    there is a simple trick to make the compiler tell you the type https://godbolt.org/z/4G1d51 – 463035818_is_not_an_ai Nov 15 '20 at 00:17
  • Not really a duplicate, but a question that starts by knowing what the type of `aAddress` is: [Pointer to class data member “::*”](https://stackoverflow.com/questions/670734/pointer-to-class-data-member). – JaMiT Nov 15 '20 at 00:20

0 Answers0