Friend function access the private members of class defined in static library
Asked Answered
L

2

2

I have a static library written in C++. I have also got the header files for the classes defined in the static library.

Can I access the private members of the classes defined in the static library introducing a friend function in class declaration ?

Lyon answered 28/3, 2012 at 8:26 Comment(3)
the devil uses: #define private publicGudgeon
nice :).......but this will not work every-timeLyon
@smerlin: I would avoid that. From a legalese point view, this is in itself undefined behavior because private is a reserved identifier (a compiler could produce an error and refuse to compile or silently ignore your directive). Second, the layout of a class is dependent on the access level of the members. Though it is a rarely use feature, you could introduce subtle bugs by having different parts of the program expecting a different memory layout for the same object.Singapore
G
2

You mean you want to change the headers that are shipped with the library? It's in no way guaranteed that adding friend declarations there will work. You might mess up the linking part, even if your compiler says it's ok.

Also, if those members are private, you just don't access them.

Griffen answered 28/3, 2012 at 8:29 Comment(7)
Can you please ellaborate on: How it might be a problem?Motorize
@Als I tried something similar a while back on Visual Studio. I edited the header myself and replaced a private with public, and I got unresolved externals. Might not be an issue on gcc, but I'm pretty sure modifying the header after the library is built is not a good idea.Griffen
@Luchian : Have you tried to introduce a friend function in the class declaration and see if you can access the private members ?Lyon
@Lyon I already told you it could compile, but that doesn't make it right.Griffen
@Als: technically, it is undefined behavior (an entity should be defined by the exact same sequence of tokens in all TUs that compose a program). Practically, I too am curious as to what might happen (and why).Singapore
Should we consider this as a loop hole in the c++ implementation ??Lyon
@Lyon it's not a loophole if it's undefined.Griffen
S
1

It is technically undefined behavior to use a different sequence of tokens to define the same entity (here a class) in different Translation Units.

Whatever the technic you use, as long as it alters the sequence of tokens composing it, it is evil from the Standard point of view (though likely to work in practice).

Johannes discovered a way to do so while respecting the Standard. It is based on the fact that even though a is a private attribute in class A, &A::a can be written in contexts that cannot write A.a (perhaps an oversight in the Standard ?).

Core method:

template<typename Tag, typename Tag::type M>
struct Rob { 
  friend typename Tag::type get(Tag) {
    return M;
  }
};

// use
struct A {
  A(int a):a(a) { }
private:
  int a;
};

// tag used to access A::a
struct A_f { 
  typedef int A::*type;
  friend type get(A_f);
};

template struct Rob<A_f, &A::a>;

int main() {
  A a(42);
  std::cout << "proof: " << a.*get(A_f()) << std::endl;
}

Extension for simplicity:

template<typename Tag, typename Member>
struct TagBase {
  typedef Member type;
  friend type get(Tag);
};

struct A_f : TagBase<A_f, int A::*> { };

EDIT:

This trick is (amusingly) explicitly allowed by the Standard

§14.7.2/12 The usual access checking rules do not apply to names used to specify explicit instantiations. [...]

Singapore answered 28/3, 2012 at 9:1 Comment(4)
I'm familiar with the post, but &A::a is still not legal. At least I don't think it is. Under MSVS it doesn't compile, and he failed to provide a quote from the standard when I asked him to, so I'm reserved about this solution. https://mcmap.net/q/598315/-calling-private-method-in-cGriffen
@LuchianGrigore: I would be happy to check, but I cannot even find the reference describing the syntax &A::a in the Standard. pointer to member yield only a few reference... do you know the term to use or where is the syntax described ?Singapore
I have no clue, but I doubt you'd find something saying it's legal. You are, in fact, trying to get the address of a private member. Don't see how or why that would be allowed by the standard.Griffen
@LuchianGrigore: well, I decided to put the SO community on this issue. Hopefully someone will find a clue in the Standard as to whether it's actually allowed or not...Singapore

© 2022 - 2024 — McMap. All rights reserved.