0

I'm working on a project written in both C and C++. The C part has a macro used to get a pointer to an object from a pointer to one of its members

#define START_OF_OBJ(ptr, type, member)({\
    const __typeof__(((type *)0)->member)* mptr = (ptr);\
    (type *)((char *)mptr - __builtin_offsetof(type, member)); })

It works fine for structs, but not as well with pointers to protected members of C++ classes. E.g. when compiling

class A {
    public:
        int a;
        int *getb() { return &b; }

    protected:
        int b;
};

int main(void)
{
    A obj;

    int *pb = obj.getb();

    A* a = START_OF_OBJ(pb, A, b);
}

with g++ -Wno-invalid-offsetof, it will - as expected - report errors for ((type *)0)->member and __builtin_offsetof(type, member) for accessing a protected member variable.

Is there a more elegant solution than making the function using the macro a class friend?

Uri Raz
  • 435
  • 1
  • 3
  • 15
  • The general problem here is not the MACRO but the protected restriction itself. I am not aware of a solution to get access to protected members without having a friend class. – RoQuOTriX Aug 02 '22 at 09:41
  • 4
    You might be interested by http://bloglitb.blogspot.com/2010/07/access-to-private-members-thats-easy.html. it allow to access to most private/protected stuff legally (without UB). – Jarod42 Aug 02 '22 at 09:45
  • 2
    If you're going to do that you may as well just make everything public. – Retired Ninja Aug 02 '22 at 09:49
  • 2
    _"...The C part has a macro used to get a pointer to an object from a pointer to one of its members..."_ how do you expect a `C` program / macro to parse a `class` ? – Richard Critten Aug 02 '22 at 09:50
  • @RichardCritten The macro is in a .h file, which compiles for both C and C++. When called with a class as a parameter, its from C++ code. – Uri Raz Aug 02 '22 at 10:08
  • 3
    @Uri - If you want to access a variable from the outside, why make it protected in the first place? And there really is no protection anyway, as you could do `*pb = 5;` and destroy the value. – BoP Aug 02 '22 at 10:14
  • Why do you actually need it? `&obj` is a pointer to the object and `pb` is a pointer to its member. – 463035818_is_not_an_ai Aug 02 '22 at 11:40
  • No, absolutely not. `offsetof` is a C thing; it doesn't work for types that are not [standard layout](https://en.cppreference.com/w/cpp/language/classes#Standard-layout_class). – Pete Becker Aug 02 '22 at 13:30

0 Answers0