constexpr的功能参数是什么?

时间:2016-09-02 03:55:47

标签: c++11 clang constexpr

我们正在尝试加速Clang和Visual C ++下的一些代码(GCC和ICC可以)。我们思想我们可以使用constexpr告诉Clang一个值是一个编译时常量,但它导致编译错误:

$ clang++ -g2 -O3 -std=c++11 test.cxx -o test.exe
test.cxx:11:46: error: function parameter cannot be constexpr
unsigned int RightRotate(unsigned int value, constexpr unsigned int rotate)
                                             ^
1 error generated.

以下是简化案例:

$ cat test.cxx
#include <iostream>

unsigned int RightRotate(unsigned int value, constexpr unsigned int rotate);

int main(int argc, char* argv[])
{
  std::cout << "Rotated: " << RightRotate(argc, 2) << std::endl;
  return 0;
}

unsigned int RightRotate(unsigned int value, constexpr unsigned int rotate)
{
  // x = value; y = rotate
  __asm__ ("rorl %1, %0" : "+mq" (value) : "I" ((unsigned char)rotate));
  return value;
}
GCC和ICC会做正确的事。他们认识到表达式2RightRotate(argc, 2)之类的值不能像我们所知的那样在物理世界的规律下发生变化,它会将2视为编译时常量并将其传播到汇编代码。

如果我们删除constexpr,那么Clang和VC ++会将函数设置为rotate REGISTER,这比rotate IMMEDIATE慢3倍。

我们如何告诉Clang函数参数rotate是一个编译时常量,它应该汇编成rotate IMMEDIATE而不是rotate REGISTER

1 个答案:

答案 0 :(得分:4)

您可以使用非类型模板参数:

template <unsigned int rotate> RightRotate(unsigned int value) {
     ...
}

然后您将其调用为

RightRotate<137>(argument); // rotate is 137 here