我正在使用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/
如果你知道如何让编译器警告这个或类似的东西我会很感激
答案 0 :(得分:2)
myStrlen(pruVar)
可以在编译时进行评估;编译器只是选择不在这种情况下。
如果要强制编译器在编译时对其进行评估,或者如果不可能则出错,请将结果分配给constexpr
变量:
constexpr unsigned int size = myStrlen(pruVar);
^^^^^^^^^
您还可以使用enum
或std::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))};