当在编译时无法评估constexpr时,gcc中有一种方法可以获得警告吗?

时间:2015-06-09 12:23:01

标签: gcc g++ c++14 constexpr

我正在使用gcc 5.1.0(c ++ 14),我正在尝试使用constexpr。非常讨厌验证我实现的constexpr是否在编译时进行了评估。我找不到任何标志来获得有关这种情况的警告。

这是一个例子: example.cpp -----------------------------------------

#include <stdlib.h>

const char pruVar[] = "12345678901234567";


[[gnu::noinline]] constexpr unsigned int myStrlen(const char* cstr)
{
    unsigned int i=0;
    for(;cstr[i]!=0;++i);
    return i; 
}

struct CEXAMPLE
{
    unsigned int size;
    constexpr CEXAMPLE(const char* s): size(myStrlen(s))
    {
    }
};

int main(void)
{
    CEXAMPLE c(pruVar);
    unsigned int size = myStrlen(pruVar);
    void* a = malloc(c.size + size);
    if (a != nullptr)
        return 0;
    else
        return 1;
}

在示例中,CEXAMPLE :: CEXAMPLE在编译时进行评估,包括对myStrlen的调用,但是在运行时正在对main中的myStrlen进行求值。我必须知道这一点的唯一方法是查看汇编程序。这个网站也很有用:http://gcc.godbolt.org/

如果你知道如何让编译器警告这个或类似的东西我会很感激

2 个答案:

答案 0 :(得分:2)

myStrlen(pruVar) 可以在编译时进行评估;编译器只是选择不在这种情况下。

如果要强制编译器在编译时对其进行评估,或者如果不可能则出错,请将结果分配给constexpr变量:

constexpr unsigned int size = myStrlen(pruVar);
^^^^^^^^^

您还可以使用enumstd::integral_constant

enum : unsigned int { size = myStrlen(pruVar) };
std::integral_constant<unsigned int, myStrlen(pruVar)> size;

答案 1 :(得分:0)

基于必须在编译时评估模板参数的事实,可以使用辅助模板。

namespace helper {
template<class T, T v> constexpr T enforce_compiletime() {
    constexpr T cv = v;
    return cv;
}
}

#define compiletime(arg) ::helper::enforce_compiletime<decltype(arg), (arg)>()

这允许编译时强制执行而无需额外的constexpr变量,这对于计算值查找表非常方便。

constexpr uint32_t bla(uint8_t blub) {
    switch (blub) {
        case 5:
            return 22;
        default:
            return 23;
    }
}

struct SomeStruct {
    uint32_t a;
    uint32_t b;
};

SomeStruct aStruct = {compiletime(bla(5)), compiletime(bla(6))};