如何在编译时检查内联函数的参数是否已知?

5 c++ static inline constants

我有一个性能关键的内联函数.它根据参数生成一些数据.我希望编译器优化所有调用的数据生成,其中参数在编译时是已知的.问题是我无法强制编译器将优化数据从堆栈中放入静态常量,因为static当参数不是编译时常量时,标记数据会破坏这种情况.堆栈上的常量数据会影响性能.有没有办法推断(可能使用templates/boost :: enable_if),参数是编译时常量并选择适当的数据生成实现?

澄清

基本上我有类似以下内容:

struct Data {
     int d_[16];
};

inline Data fun(int param)
{  //param can sometimes be a compile-time constant

    ... //generate the data
    Data res = {gen0, gen2, gen3, ..., gen15}; //put the data into result
    return res;
}
Run Code Online (Sandbox Code Playgroud)

所以当param不是编译时常量时,我​​们只生成所有数据并返回.
param是已知的,编译器可以优化数据产生出来.但是,它无法优化以下线路并生成大量代码,只是将res成员设置为已知数据(数据嵌入到程序代码中).我希望编译器创建一个静态常量,然后将其复制到返回对象(这比执行包含嵌入数据的代码更快).由于这是内联函数,因此即使是副本也可能不是必需的.

放弃

这个问题与如何使用内联函数的不同重载不同,具体取决于编译时参数?.这是更普遍的问题.

nix*_*gle 1

这不是可移植的,但在 GCC 和 Clang 上可能有一个__builtin_constant_p编译器函数。这可以让您询问编译器在编译期间是否知道变量的值。你可以这样使用它:

void f(int arg) {
  if (__builtin_constant_p(arg) && arg == 0) {
    // Handle case where arg is 0 AND known at compile time.
  } else {
    // Generic code.
  }
}
Run Code Online (Sandbox Code Playgroud)

这样,else如果arg在编译时已知并且为 0,编译器将不会在分支中生成代码。

使之更可移植的一个有用技巧可能是使用一些宏黑客技术。

#ifdef __GNUC__
#  define CONSTANT_P(x) __builtin_constant_p(x)
#else
#  define CONSTANT_P(x) 0
#endif
Run Code Online (Sandbox Code Playgroud)

根据需要添加支持与此类似的其他编译器,您现在可以使用它,而不会在不支持此功能的编译器上产生额外开销。也就是说,那些编译器,如果它们有任何价值的话,将消除CONSTANT_P分支,只留下通用代码。