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

There is a way in gcc to get a warning when a constexpr can't be evaluated at compile time?

我正在使用 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 的调用在运行时求值。我必须知道的唯一方法是查看 assembler.This 网站也非常有用:http://gcc.godbolt.org/

如果您知道如何让编译器对此或类似的事情发出警告,我将不胜感激

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;

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

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))};