Search code examples
c++undefined-behavior

Can macro-dependant access specifiers in a class definition result in undefined behavior?


Let's say I have the following two class definitions (only the access specifier for bar() is different, everything else is the same):

class MyClass {
public:
    void foo();
    void bar();   // bar() is public

private:
    int member;
};

and

class MyClass {
public:
    void foo();

private:
    void bar();   // bar() is private
    int member;
};

Does a compiler consider the classes to be "different" in terms of what code the compiler produces? (Or in other words: Does the compiler treat it differently apart from access permission checking?)

This is the same question as: Can the following code cause any trouble like undefined behavior? (Provided that it is compiled in different units, with or without X being defined, and linked together afterwards.)

class MyClass {
public:
    void foo();

#ifdef X
private:
#endif
    void bar();

private:
    int member;
};

I'm interested in a compiler-independent answer as well as in a GCC-specific one (as this is my primary target compiler).

This becomes interesting if we want to "simulate" things like package private from the Java world in C++ by defining a specific macro within the "package".


Solution

  • It's definitely undefined behaviour to violate the one-definition rule, which requires that all definitions of the same class type be identical.

    Note that the memory layout of a class is only specified within each access level, so changing access levels can very realistically lead to a different memory layout of the class.