简体   繁体   中英

offsetof on standard-layout class?

#include <iostream>
#include <cstddef>
class Foo
{
    int a;
    int b;
    float c;
};
int main()
{
    Foo foo;
    std::cout << offsetof(Foo, b) << std::endl;
    return 0;
}

The above code could not compile using gcc-4.8.2 or vc++11. The error message is could not access private member b in class Foo.

But according to the standard, offsetof should support standard-layout class and Foo is a standard-layout class.

Is this a defect of gcc-4.8.2 or vc++11, or my understanding of the c++ standard is wrong?

Data members in a class are private by default . they can be accessed from main only if it is declared under public .Or you can access them from main by declaring a function in the class under public and calling it from main. since the functions in the class can access the data members from the class,you can get access to the private data members.

offsetof is defined as a macro and therefore it can not bypass the access controls and gain access to private members , we can see that this is the case by going to draft C++ standard section 17.6.1.2 Headers paragraph 5 which says ( emphasis mine ):

Names which are defined as macros in C shall be defined as macros in the C++ standard library, even if C grants license for implementation as functions. [ Note: The names defined as macros in C include the following: assert, offsetof , setjmp, va_arg, va_end, and va_start. —end note ]

So there are hacks that can allow you to access the private member of a class in a standard way but if we go back to the C99 draft standard which the draft C++ standard falls back on for offsetof then we see in section 7.17 Common definitions paragraph 3 says ( emphasis mine ):

   offsetof(type, member-designator)

which expands to an integer constant expression that has type size_t, the value of which is the offset in bytes, to the structure member (designated by member-designator), from the beginning of its structure (designated by type). The type and member designator shall be such that given

   static type t;

then the expression &(t.member-designator) evaluates to an address constant .

which won't be the case if you are trying to access a private member from outside the class.

class members default to private. List them as public, or make Foo a struct (because struct members default to public) and the above works, else main isnt permitted to access b, and offsetof is considered an access.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM