Re: [eigen] proposal to use static const integer class members instead of enum values

[ Thread Index | Date Index | More lists.tuxfamily.org/eigen Archives ]




2014-12-13 10:47 GMT-08:00 Marc Glisse <marc.glisse@xxxxxxxx>:
On Sat, 13 Dec 2014, Benoit Jacob wrote:

Eigen does this for storing integer constants on a class:

class C {
 enum { SomeConstant = SomeValue };
};

Most other C++ code (including libstdc++ and libc++) do this instead:

class C {
 static const some_integer_type SomeConstant = SomeValue;
};

You are missing the extra:

const some_integer_type C::SomeConstant;

Otherwise, passing this value by reference may yield undefined references, especially at -O0.

That would be the case for a static-storage non-constant integer, but not for a static-storage constant integer, see:
http://stackoverflow.com/questions/9219898/why-can-you-initialize-a-static-const-variable-inline-but-not-a-plain-static-c

This program builds in C++98 mode:

#include <iostream>

using namespace std;

struct C {
    static const int foo = 123;
    static const bool bar = true;
};

int main()
{
    cout << C::foo << endl;
    cout << C::bar << endl;
}

 

I don't think libstdc++ uses that much. If SomeConstant is "value", it tries to derive from integer_constant instead.

True, I was forgetting that it used that. I don't remember the motivation for that idiom, though. Does it make the compiler's job easier? Should we do the same?

 


I think we should switch to that too. The upside is clear: being able to
explicitly choose a specific integer type or bool.

I don't think there is a significiant downside (anymore). Early _expression_
templates libraries tended to use enums (in particular, TVMET, on which the
early attempt at Eigen2 found in the 35 first csets of the repo was based,
uses enums). In theory, enums are the only true compile-time constants in
C++, aside from literals. In practice, because C++ says it's undefined
behavior to overwrite a static-storage constant, the compiler is free to
always assume that static-storage constants always have the same value as
the literal value that was originally assigned to them, and so in practice
reading from a static-storage constant is never a memory access.

A downside of anonymous enums is that in C++03 you couldn't use them as template parameters.

And another downside is that you can't use them as bitfields, have to cast them to integers beforehand.

Benoit
 


If you agree with the general idea, the next question is: do you prefer
small incremental patches or a big bulky patch? What would be less
disruptive to your workflow? Or... maybe I should instead make a parser
that does this replacement automatically so one can also apply it to local
branches.

--
Marc Glisse




Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/