Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 编译时可选代码标准问题_C++_Templates_C++14 - Fatal编程技术网

C++ 编译时可选代码标准问题

C++ 编译时可选代码标准问题,c++,templates,c++14,C++,Templates,C++14,对于嵌入式系统,我编写了一段代码,它根据编译时和运行时选择的变量生成延迟。编译时版本归根结底是写尽可能多的NOP指令,以达到预期的CPU周期计数 主要部分如下: #define IS_CONSTEXPR(...) __builtin_constant_p(__VA_ARGS__) #define FORCE_INLINE __attribute__((always_inline)) template <int a> struct Nop { __attribut

对于嵌入式系统,我编写了一段代码,它根据编译时和运行时选择的变量生成延迟。编译时版本归根结底是写尽可能多的NOP指令,以达到预期的CPU周期计数

主要部分如下:

#define IS_CONSTEXPR(...) __builtin_constant_p(__VA_ARGS__)
#define FORCE_INLINE      __attribute__((always_inline))

template <int a> struct Nop { 
    __attribute__((always_inline)) static void nop() {
      asm __volatile__("nop");
      Nop<a-1>::nop();
    }
};
template <> struct Nop<0> {
    __attribute__((always_inline)) static void nop() {}
};

void bar(int x) { 
    // TODO: Make an asm version of this to avoid depending on compiler optimization
    for (int i = 0; i < x; i++) 
      Nop<1>::nop(); 
}

template <bool e, int T> struct CTorRT
{   
  FORCE_INLINE CTorRT(int) { 
    if (T == 0) return;
    if (T >= 40) bar(T - 10); // Switch to loop based delay now, since it's above the loop calling overhead 
    else Nop<T>::nop(); // Let's generate a bunch of nop!
  }
};

template <int T> struct CTorRT<false, T>
{
    FORCE_INLINE CTorRT(int v) { bar(v); }
};


#define DELAY_CYCLE(X) { CTorRT<IS_CONSTEXPR(X), IS_CONSTEXPR(X) ? X : 0> a(X); }


int main()
{
   int d = 10;
[...]
   DELAY_CYCLE(30);  // Generates 30 NOP 
   DELAY_CYCLE(d);   // Call bar(10) and loop 10 times over a single NOP loop
[...]
}

#定义为常量(…)(内置常量)
#定义强制\内联\属性\内联((始终\内联))
模板结构Nop{
__属性(总是内联的)静态void nop(){
挥发性有机物(“nop”);
所有编译器上的Nop(最旧的编译器除外)

然而,我很难理解为什么它没有在这一部分中断:
CTorRT
A
是一个编译时常量(constexpr),但是X可以是一个动态变量,因此,我的理解是
A?X:0
不是一个constexpr(即使结果在所有情况下都是一个常量表达式)

标准的哪一部分暗示“constexpr\u bool?variable\u或_constexpr:constexpr”是一个constexpr

标准的哪一部分暗示“constexpr\u bool?variable\u或_constexpr:constexpr”是一个constexpr

没有一部分是这样的,因为
\uuuu内置常量\up
不是标准函数(或者根本不是常规函数),而且该三元函数通常不会是
constexpr
。您使用的是编译器扩展的文档化行为,而不是标准语言

委员会特别处理这一问题:

您还可以在静态数据的初始值设定项中使用
\uuuu内置常量\up

static const int table[]{
__内置常数(表达式)?(表达式):-1,
/* … */
};
这是一个可接受的初始值设定项,即使表达式不是常量表达式


也就是说,GCC有效地实现了
?constepr
,只是为了它们自己的内置。这并不意味着除了使用这样的编译器扩展之外,没有任何方法可以实现同样的事情。

宏“DELAY\u CYCLE(X)”中的
CTorRT
在哪里关于XSo什么?宏不是代码。你熟悉宏的工作原理吗?基本上,它是这样工作的:如果X是constexpr,它被用作CTorRT模板的模板参数。如果X不是constexpr,模板参数是0,X被用于CTorRTSure的构造函数,但这在宏定义中意味着什么都没有。现在,尝试使用一个非常量宏来使用这个宏,看看它是否工作。好的,很清楚。所以问题归结为C++中的2种不同的实现(编译时间和运行时)。