← Back to team overview

kicad-developers team mailing list archive

Re: Damned the 'undefined global constructor order'

 

On 06/09/2014 03:50 PM, Dick Hollenbeck wrote:
> On 06/09/2014 03:42 PM, Dick Hollenbeck wrote:
>>
>> Attached are two that work using the "set()" function.
>>
>>
>> As a third choice:
>>
>> You could also create a new constructor that actually takes an int64_t bitmap, and use
>>
>> GetLayerMask() to build it.
>>
>> However I would rename GetLayerMask() to something more concise:
> 
> From previous experience I know that the inline function, here called LMSK() would have
> be called via the static constructor.  If this is changed to a MACRO, then the
> pre-processor will create the int64_t, and you only have to call the one function, the
> constructor.  Not the two calls to the LMSK().
> 
> IOW, the compiler cannot pre-process even *inline functions* when they are part of a
> static constructor.  It can however handle macros.


That is attached, the #else now uses a *macro* LMSK() and I'm sure only results in one
call to the static construction logic.


#include <stdio.h>
#include <stdint.h>

//#define __STDC_FORMAT_MACROS

#include <inttypes.h>
#include <vector>


#include <bitset>

enum LAYER_NUM
{
    LAYER_CU_FRONT,
    LAYER_CU_BACK,
};

#define LMSK( x )   (1ULL << (x))

#if 0

typedef std::bitset<64>     LAYER_SET;

const LAYER_SET CU_EXTERNAL = LAYER_SET().set( LAYER_CU_FRONT ).set( LAYER_CU_BACK );

int main( int argc, char** argv )
{
    printf( "value %" PRIu64 "\n", *(int64_t*) &CU_EXTERNAL );

    return 0;
}

#else

typedef std::bitset<64> BASE_SET;

class LAYER_SET : public BASE_SET
{
public:
    static const LAYER_SET   CU_EXTERNAL;

    // this should not be inline.
    LAYER_SET( uint64_t aMask )
    {
        uint64_t    mask = 1;

        for( unsigned i=0; i<sizeof( aMask ) * 8;  ++i, mask <<= 1 )
        {
            if( aMask & mask )
                set( i );
        }
    }

    LAYER_SET() : BASE_SET() {}

    LAYER_SET& set( int index )
    {
        return (LAYER_SET&) BASE_SET::set( index );
    }

    LAYER_SET& operator | ( int index )
    {
        return set( index );
    }
};


//const LAYER_SET LAYER_SET::CU_EXTERNAL = LAYER_SET().set( LAYER_CU_FRONT ).set( LAYER_CU_BACK );
const LAYER_SET LAYER_SET::CU_EXTERNAL = LMSK( LAYER_CU_FRONT ) | LMSK( LAYER_CU_BACK );


int main( int argc, char** argv )
{
    printf( "value %" PRIu64 "\n", *(int64_t*) &LAYER_SET::CU_EXTERNAL );

    return 0;
}


#endif





Follow ups

References