Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why offsetof implementations strangely differs on C and C++?

Tags:

c++

c

offsetof

I opened stddef.h and saw this:

#if defined _MSC_VER && !defined _CRT_USE_BUILTIN_OFFSETOF
    #ifdef __cplusplus
        #define offsetof(s,m) ((size_t)&reinterpret_cast<char const volatile&>((((s*)0)->m)))
    #else
        #define offsetof(s,m) ((size_t)&(((s*)0)->m))
    #endif
#else
    #define offsetof(s,m) __builtin_offsetof(s,m)
#endif

In branch of __cplusplus (In case of C++ compiler) there is very strange implementation, I think it's redundant. Else branch (case of C compiler) has simpler calculation of field offset. And I tested it, it works. For what used this strange casts and type qualifiers in first case?

like image 219
Artem Selivanov Avatar asked Dec 18 '22 02:12

Artem Selivanov


1 Answers

operator & can be overloaded for the type of m, so &((s*)0)->m) would call that operator & instead of taking m's address.

And const volatile is there in the reinterpret_cast's type so that it works even when m is const and/or volatile.

Note that in C++11, there is std::addressof(x) which always takes the address of x regardless of operator & overloads. It's likely to be implemented in a similar fashion to what you see in the question.

like image 73
Angew is no longer proud of SO Avatar answered Dec 24 '22 01:12

Angew is no longer proud of SO