← Back to team overview

kicad-developers team mailing list archive

Re: Damned the 'undefined global constructor order'

 

On 06/10/2014 01:33 AM, Lorenzo Marcantonio wrote:
> On Mon, Jun 09, 2014 at 03:42:23PM -0500, Dick Hollenbeck wrote:
>> You could also create a new constructor that actually takes an int64_t bitmap, and use
> 
> For the builtin layers could work, however in general there could be
> more than 64.
> 
>> GetLayerMask() to build it.
>>
>> However I would rename GetLayerMask() to something more concise:
> 
> GetLayerMask is no more, however I got the message.
> 
>>
>> const LAYER_SET LAYER_SET::IMPORTANT_SET = LMSK( LAYER_CU_FRONT ) | LMSK( LAYER_CU_BACK );
>> P.S. I sort of LAYER_SET better than LAYER_MSK as a type name.
> 
> LSET then is even better :D


I too like LSET.

> 
>> const LAYER_SET CU_EXTERNAL = LAYER_SET().set( LAYER_CU_FRONT ).set( LAYER_CU_BACK );
> 
> 
> My problem was another one... ATM I can already write
> 
> const LSET CU_EXTERNAL = // <<< see, I like it :D
>     LAYER_CU_FRONT | LAYER_CU_BACK;
> 
> but in another place I can't say
> 
> const LSET MORE_CU = LAYER_CU_WHATEVER | CU_EXTERNAL;
> 
> since the MORE_CU initialization *could* be run before CU_EXTERNAL's
> one. AFAIK there is a gcc attribute to order them (but it's a PITA to
> track dependencies by hand).
> 
> The current 'best' solution I've found is
> 
> LSET CU_EXTERNAL()
> {
>     static const LSET this_value = LAYER_CU_FRONT | LAYER_CU_BACK;
>     return this_value;
> }
> 
> since it's guaranteed that this_value constructor get run on the first
> call, and only then.
> 

But then aren't you having to supply () when referencing it?  It is after all now a
function call.

Let's be honest, the bitwise ORing is convenient, and I think that's why you wanted to
preserve it.  The '|' operator is well understood.

I don't have a problem with two sets of #defines:

1) bitshifted mask

2) the LAYER_NUM enum.

If both were spelled exactly the same, with a minor suffix change, this would be OK to
predefine them.

If we then use int64_t to distinguish the masks, this gives you a disambiguating
characteristic for the compiler.

1) mask: uint64_t
2) index (LAYER_NUM) enum, interchangeable with int in some contexts.

I don't see the compiler confusing these:

1) operator <> ( int ) or operator <> ( LAYER_NUM ), and
2) operator <> ( uint64_t )


Eventually we can work our way out of the uint64_t with time, should boards get thicker
than 64 conceptual and actual layers.  But we have some time.










Follow ups

References