May pointer to members circumvent the access level of a member?

浪尽此生 提交于 2019-12-08 23:01:48

问题


Our infamous litb has an interesting article on how to circumvent the access check.

It is fully demonstrated by this simple code:

#include <iostream>

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;
}

Which compiles and runs (output 42) with gcc 4.3.4, gcc 4.5.1, gcc 4.7.0 (see user1131467's comment) and compiles with Clang 3.0 and Comeau C/C++ 4.3.10.1 in C++03 strict mode and MSVC 2005.

I was asked by Luchian on this answer in which I used it to justify that it was actually legal. I agree with Luchian that it is weird, however both Clang and Comeau are close contenders for the most "Standard" compilers available (much more so than MSVC by default)...

And I could not find anything in the drafts of the Standards I have available (n3337 being the last version I got my hands on).

So... can anyone actually justifies that it is legal or not ?


回答1:


Yes, it's legal. The relevant text is at §14.7.2/12, talking about explicit template instantiation:

12 The usual access checking rules do not apply to names used to specify explicit instantiations. [ Note: In particular, the template arguments and names used in the function declarator (including parameter types, return types and exception specifications) may be private types or objects which would normally not be accessible and the template may be a member template or member function which would not normally be accessible. — end note ]

Emhpasis mine.




回答2:


The code is clearly illegal (and requires a compile time diagnostic). In the line:

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

the expression A::a accesses a private member of A.

The standard is very clear about this: “Access control is applied uniformly to all names, whether the names are referred to from declarations or expressions.“ (§11/4, emphasis added). Since a is a private name in A, any reference to it outside of A is illegal.



来源:https://stackoverflow.com/questions/9907328/may-pointer-to-members-circumvent-the-access-level-of-a-member

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!