How to use a private member from outside the class
source link: https://quuxplusone.github.io/blog/2020/12/03/steal-a-private-member/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
How to use a private member from outside the class
Am I missing some subtle mechanism by which “unused” private members might actually be referenced from other TUs?
Indeed, I was! Check this out (Godbolt):
struct S {
private:
static int private_static_data;
};
int S::private_static_data = 42; // Optimize this away?
// Meanwhile, in some other TU...
static int *f();
template<int *x>
struct F {
friend int *f() { return x; }
};
template struct F<&S::private_static_data>;
int steal_private_data() {
return *f();
}
According to [temp.spec]/6,
the template arguments of explicit instantiation declarations are permitted
to name “private types or objects that would normally not be accessible” —
such as S::private_static_data
in this case.
So we can instantiate F<&S::private_static_data>
, even though we cannot
actually refer to that instantiation by name afterwards. This “leaks” the
private data of S
into F
. F
leaks it out again via the global function
f()
. And then anyone can call f()
to obtain a pointer to S
’s private
data.
Therefore, although the compiler of TU #1 can see that none of S
’s members and
friends use S::private_static_data
, it cannot conclude that
the definition of S::private_static_data
is unused. Other object files
may indeed refer to that linker symbol. So the compiler must generate code for it.
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK