Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Clang report "constexpr if condition is not a constant expression" while GCC is ok [duplicate]

I'm using clang 9.0.1 and gcc 9.2.1 on x64 Linux, both with --std=c++17 (or --std=c++2a).

Gcc can build the following example without any error or warning, while clang++ reports error: constexpr if condition is not a constant expression on both if constexpr lines. (btw, on my MacBook, Apple clang-11.0.0 reports the same error too.)

MCVE:

#include <utility>

enum class TopicType {
    MarketData = 'M',
    Timer = 'T',
};

template<class Topic>
struct TopicBase {
    constexpr static TopicType type() { return Topic::type; };
    const Topic& topicImp;
    explicit TopicBase(const Topic &t) : topicImp(t) {}
};

struct MarketDataTopic {
    static constexpr TopicType type{TopicType::MarketData};
};

struct TimerTopic {
    static constexpr TopicType type{TopicType::Timer};
};

template<class Topic>
int subscribe(TopicBase<Topic>&& topic) {

    if constexpr (topic.type() == TopicType::MarketData) { // <-- clang++ reports error here
        return 1;
    }
    if constexpr (topic.type() == TopicType::Timer) { // and error here
        return 2;
    }

    return -1;
}

int main(int argc, const char **argv) {

    MarketDataTopic m{};
    TimerTopic t{};

    TopicBase<MarketDataTopic> b1{m};
    TopicBase<TimerTopic> b2{t};

    subscribe(std::move(b1));


    return 0;
}

Online compiler https://godbolt.org/z/rARi_N has the same result.

So which compiler is right about this? And if it is an error, how to fix it for clang?

like image 266
halfelf Avatar asked Oct 15 '22 05:10

halfelf


1 Answers

Well you can do this to make it work for clang:

template<class Topic>
int subscribe(TopicBase<Topic>&& topic) {
    using myType = TopicBase<Topic>;
    if constexpr (myType::type() == TopicType::MarketData) { // <-- clang++ reports error here
        return 1;
    }
    if constexpr (myType::type() == TopicType::Timer) { // and error here
        return 2;
    }

    return -1;
}

Run live

Most probably that's a bug in clang. Better report it.

like image 102
theWiseBro Avatar answered Oct 19 '22 01:10

theWiseBro