← Back to team overview

kicad-developers team mailing list archive

Damned the 'undefined global constructor order'

 

I'm trying to rework the LAYER_MSK in a more flexible container,
whatever the decision about the structure will be. The idea is to remove
all the mask constants and only use the layer indices, together with
appropriate operator definition.

That part more or less works (using a bitset but that's not important).
At the moment I have a 'layer set algebra' so that I could say:

LAYER_MSK mask = CU_FRONT_LAYER | CU_BACK_LAYER;

and then

mask &= ~CU_BACK_LAYER;

or even

mask -= CU_BACK_LAYER;

(since bit operation have no meaning on a layer index, operators works
them as masks). This BTW completely remove the GetLayerMask function
which was a nuisance.

For the commonly uses global masks I've defined static members like
this:

const LAYER_MSK LAYER_MSK::CU_EXTERNAL = 
    CU_FRONT_LAYER | CU_BACK_LAYER;

So layer I can say

if (aMask & LAYER_MSK::CU_EXTERNAL) // do stuff if uses outer layers

However, the compiler in C++98 *does not* fold the expressions, since it
can't execute operator during compilation. That would be done in C++11
with constexpr and only with some (strong) restrictions.

That means that LAYER_MSK::CU_EXTERNAL will be initialized using
a static constructor (once at the beginning); mask &= ~CU_BACK_LAYER;
would *each time* compute the negation and then apply the & operator.
Since masks will maybe be dynamic (in length) anyway that could be
acceptable.

However, in the layer setup preset, I would like to use:

static const LAYER_MSK presets[] =
{
    LAYER_MSK(),  // shift the array index up by one, matches with "Custom".
    EDGE_LAYER | CU_FRONT_LAYER | CU_BACK_LAYER | LAYER_MSK::TECH_FRONT,

...

And that (if it works) is only by chance: LAYER_MSK::TECH_FRONT need to
be statically constructed, exactly like preset. Depending on the whims
of the linker the preset initialization *could* be run before the one of
LAYER_MSK::TECH_FRONT. Not good.

How could I solve this?

Solution 1) explode in the presets the whole list of layers in TECH_FRONT. Not
exactly elegant

Solution 2) convert the TECH_FRONT constant to a function which always return the
correct value; best way to fix it I found until now (however every time
it recomputes the whole or chain...)

Solution 3) the preset could be moved inside the only function using
it... sadly not a general case solution

Solution 4) ??? anybody knows some idiomatic form/magic pattern to avoid
the problem?

-- 
Lorenzo Marcantonio
Logos Srl


Follow ups