C++ 编译时可选代码标准问题
对于嵌入式系统,我编写了一段代码,它根据编译时和运行时选择的变量生成延迟。编译时版本归根结底是写尽可能多的NOP指令,以达到预期的CPU周期计数 主要部分如下: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
#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种不同的实现(编译时间和运行时)。