c++ - Why must const class members be static to be properly optimised? -
given:
class foo { const int x = 5; public: inline int get() { return x; } }; class bar { static const int x = 5; public: inline int get() { return x; } }; int fn0(foo& f) { return f.get(); } int fn1(bar& b) { return b.get(); }
compiled output gives memory fetch read value of x
in fn0()
, whereas adding static
results literal 5
being inlined in fn1()
. implication caller get()
can optimised if using constant in place of get()
when integer constant static.
i have more complex situations static
not appropriate. derived classes initialise x
different values through constructor; each of classes x
constant , class methods optimised, preceeding static
case, if get()
evaluated true constant.
in fact, commonest case initialisation of references in base class:
class foo { int& x; public: foo(int& init) : x(init) {} inline int get() { return x; } }; class bar : public foo { int m; public: bar() : foo(m) {} inline int getget() { return get(); }; int fn1(bar& b) { return b.getget(); }
here, if get()
evaluated directly bar::m
within getget()
avoid level of pointer indirection. not possible if x
static.
it's not clear me why static
necessary allow optimisation.
a static const int
member initialized in-class true constant expression, is, compile-time constant.
a non-static const int
member cannot changed after initialized, harder compiler determine statically can have 1 possible value. note brace-or-equal-initializer non-static data member used if there no mem-initializer member. means if example had this:
class foo { const int x = 5; public: inline int get() { return x; } foo() = default; foo(int x) : x(x) {} };
then foo::x
5
, if default constructor called, or else, if foo::foo(int)
called. consider happens if member made public:
class foo { public: const int x = 5; inline int get() { return x; } };
now it's possible use aggregate initialization:
foo f {42}; // f.x 42
in particular case of foo
wrote, believe true foo::x
can ever 5
, isn't easy compiler determine if foo::x
static data member. quite possibly compiler implementers didn't bother write such optimization.
Comments
Post a Comment