Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
388 views
in Technique[技术] by (71.8m points)

c++ - static_assert within constexpr constructor

I search for a method to detect a given value for a constexpr constructor is in a valid range.

The code is as follows:

class Timer0 {

constexpr uint16_t CalcPresecaler( uint32_t faktor )
{   
    uint16_t prescaler = faktor / 255;

    if ( prescaler <    1 ) return    1;  
    if ( prescaler <    8 ) return    8;  
    if ( prescaler <   64 ) return   64; 
    if ( prescaler <  256 ) return  256;
    return 1024;
}   

constexpr uint8_t PrescalerBits( uint16_t prescaler )
{   
    if ( prescaler == 1024 ) return 0b101;
    if ( prescaler ==  256 ) return 0b100;
    if ( prescaler ==   64 ) return 0b011;
    if ( prescaler ==    8 ) return 0b010;
    if ( prescaler ==    1 ) return 0b001;
    return 0b000; // should never happen
}  
    constexpr Timer0( const uint32_t sysclk, const uint32_t timerclk )
    {
        uint32_t faktor = sysclk/timerclk; 
        uint16_t prescaler = CalcPresecaler( faktor );
        uint8_t prescalerBits = PrescalerBits( prescaler );
        uint8_t compare = (faktor/prescaler)-1;
        static_assert( ???? ); << can not be used on function parameters
        OCR0=compare;
        TCCR0=0x08| prescalerBits;
        TIMSK=0x02;
    }
};
int main()
{
     Timer0 t0(  8000000, 10 );
}

I already read C++11 - static_assert within constexpr function? but I can't use throw as I am on a avr embedded target where gcc has not enabled exceptions, even if it used here for compile time checking.

Any idea how to detect at compile time that the value of compare did not exceed a given value?

question from:https://stackoverflow.com/questions/66062564/static-assert-within-constexpr-constructor

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Since you cannot throw, you can do something that is illegal in a constexpr environment.

For example, if your condition is that prescalerBits != 0, you can do:

if (prescalerBits == 0)
    *(int*)nullptr = 0;

Which should stop any compile time evaluation. If you are worried about calling this function at runtime and getting a null pointer dereference, you can guard this condition with std::is_constant_evaluated().


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...