[eigen] a few things

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


Hi List

1) Jonas asked me a few questions yesterday which made me realize that
-a) we need to completely split the "actual size at compile time" from the
"allocated size at compile time". This would allow taking a dynamic block in a 
fixed-size matrix and still not do any dynamic memory allocation when 
evaluating it. One would then be able to get rid of the block()/dynBlock() 
pair and have only one block() function in the API.
-b) we need to introduce a separate special size "Generic" alongside the 
existing "Dynamic". This would allow writing

someExpression = Eigen::zero();

instead of

someExpression = TypeOfThatExpression::zero();

To Jonas and ollupaC: I'm sorry the current Eigen API is not good enough; give 
me a few days to work that out (currently working locally with git).

2) I'm about to switch the compile-time sizes from "static const int" 
to "enum". Two reasons to do that; first it feels cleaner than having 
these "static const int" values such as "Dynamic"; second I just found this:

http://jpz-log.info/archives/2007/09/09/the-joy-of-c-templates-metaprogramming/#comment-317

and the following comments.

I am not sure I understand all what is said here so I'm asking you for 
confirmation:

when a class has a "static const int" member, this member is actually stored 
in memory somewhere in the program's memory space, while an "enum" is just 
used by the compiler and not stored in the program's memory space. Right?

If that's true, that's a good reason to go for enums, again for two reasons.
a) wasted memory. a static const int does not take much memory, but eigen 
creates so many types, and many of which are purely formal and might not 
generate any code, that the ratio "memory wasted by static const 
ints" / "memory used for code" might be non-negligible
b) more importantly (the main reason IMO) being stored in memory sounds very 
bad as it means that if the compiler somehow fails to optimize, a memory 
access is done when that value is used. While with enums, this is guaranteed 
to be optimized i.e. replaced by the literal value.

Can you confirm if so far I got it right?

Now, before going for enums, I have a few more questions.

1) when the compiler sees something like
enum MyType { First = 1, Second = 10000};
the compiler may choose as underlying integer type for MyType any type that 
can store the given values. In that case it might use "short int" 
or "unsigned int" for example. The following example,
enum MyType { First = 1, Second = -10000};
is legal and the compiler is guaranteed to choose for MyType a signed type.

Correct so far?

So I can always, regardless of the compiler, do:

enum Size { Dynamic = -1, Generic = -2 };

right?

2) Should my template parameters then be enums as well? Is this legal? Or 
should I leave them as ints?

My concern here is the following. Suppose that at some point during 
compilation, the compiler has decided that the underlying integer type 
for "enum Size" is "char"  (this counts as an integer type, right?)

Suppose then (unlikely but possible) that later the compiler finds in the 
source code an instanciation like

Matrix<float, 128, 1> myBigFixedSizeVector;

128 doesn't fit into char so what happens?
- compiler error?
- integer overflow / undefined behavior?
- or is the compiler so clever that it will first go through the whole source 
code to see what integer type is really needed?

(Well I ask about the compiler but what I really care about is the C++ 
standard i.e. I don't want to use non-standard behavior)

Is it a good idea, to work around this issue, to declare enum Size as follows?
enum Size { Dynamic = -1, Generic = -2, Dummy = INT_MAX };
in order to ensure that the underlying type is "int" ?

Thanks for your help

Cheers,
Benoit

Attachment: signature.asc
Description: This is a digitally signed message part.



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