Is the compiler allowed to optimise out private data members?

≯℡__Kan透↙ 提交于 2020-12-29 04:59:50

问题


If the compiler can prove that a (private) member of a class is never used, including by potential friends, does the standard allow the compiler to remove this member from the memory footprint of the class?

It is self-evident that this not possible for protected or public members at compile time, but there could be circumstances where it is possible regarding private data members for such a proof to be constructed.


Related questions:

  • Behind the scenes of public, private and protected (sparked this question)
  • Is C++ compiler allowed to optimize out unreferenced local objects (about automatic objects)
  • Will a static variable always use up memory? (about static objects)

回答1:


Possible in theory (along with unused public members), but not with the kind of compiler ecosystem we're used to (targeting a fixed ABI that can link separately-compiled code). Removing unused members could only be done with whole-program optimization that forbids separate libraries1.

Other compilation units might need to agree on sizeof(foo), but that wouldn't be something you could derive from a .h if it depended on verifying that no implementation of a member function's behaviour depended on any private members.

Remember C++ only really specifies one program, not a way to do libraries. The language ISO C++ specifies is compatible with the style of implementation we're used to (of course), but implementations that take all the .cpp and .h files at once and produce a single self-contained non-extensible executable are possible.

If you constrain the implementation enough (no fixed ABI), aggressive whole-program application of the as-if rule becomes possible.


Footnote 1: I was going to add "or exports the size information somehow to other code being compiled" as a way to allow libraries, if the compiler could already see definitions for every member function declared in the class. But @PasserBy's answer points out that a separately-compiled library could be the thing that used the declared private members. So we'd have to fully rule them out.

Given that, public and private members are equivalent for the purposes of such an optimization.




回答2:


If the compiler can prove that a (private) member of a class is never used

The compiler cannot prove that, because private members can be used in other compilation units. Concretely, this is possible in the context of a pointer to member in a template argument according to [temp.spec]/6 of the standard, as originally described by Johannes Schaub.

So, in summary: no, the compiler must not optimise out private data members any more than public or protected members (subject to the as-if rule).




回答3:


No, because you can subvert the access control system legally.

class A
{
    int x;
};

auto f();

template<auto x>
struct cheat
{
    friend auto f() { return x; }
};

template struct cheat<&A::x>;  // see [temp.spec]/6

int& foo(A& a)
{
    return a.*f();  // returns a.x
}

Given that the compiler must fix the ABI when A is first used, and that it can never know whether some future code may access x, it must fix the memory of A to contain x.



来源:https://stackoverflow.com/questions/65201486/is-the-compiler-allowed-to-optimise-out-private-data-members

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