我试图尽可能地了解constexpr。但是,我发现了一个我无法解释的问题(我不理解编译器对此代码片段的决定)。此代码已在X86-64 gcc 7.2上使用-O3标志进行编译,其中C ++ 17为标准(我已使用godbolt.org进行此编译)
拿这段代码:
#include <stdlib.h>
#include <stdio.h>
template <size_t N>
class constexpr_sum_array_compile_time
{
public:
inline constexpr constexpr_sum_array_compile_time ()
{
start_arr();
sum();
}
inline constexpr void start_arr()
{
for (int i = 0; i<N; ++i)
{
m_arr[i] = i;
}
}
inline constexpr void sum()
{
m_sum = 0;
for (int i = 0; i<N; ++i)
{
m_sum += m_arr[i];
}
}
constexpr int sum_res()
{
return this->m_sum;
}
private:
int m_arr[N];
int m_sum = 0;
};
#define NUMBER (4)
int main()
{
return constexpr_sum_array_compile_time<NUMBER>().sum_res();
}
简而言之,这是一个constexpr类,它创建一个给定大小的数组,然后将数组与增量值相加(arr [0] = 0,arr [1] = 1,arr [2] = 2 ... arr [n] = n)在compile_time上(至少那就是我想要的)。 如果&#34; NUMBER&#34; define在范围内:{0&lt; = NUMBER&lt; = 4或8&lt; = NUMBER&lt; = 71} 然后这个类完全优化,只返回一个值(如预期的那样)
然而!如果NUMBER在范围内:{5&lt; = NUMBER&lt; = 7或NUMBER&gt; = 72},则编译器ISN可以优化返回值。 怎么会?这些价值观有什么特别之处? 您可以在godbolt.org上查看优化,它显示原始程序集正在编译。
似乎我需要创建一个包含constexpr关键字的变量,以便允许编译器在编译时计算它。新代码是:
#include <stdlib.h>
#include <stdio.h>
template <size_t N>
class constexpr_sum_array_compile_time
{
public:
inline constexpr constexpr_sum_array_compile_time() : m_arr(), m_sum(0)
{
start_arr();
sum();
}
inline constexpr void start_arr()
{
for (int i = 0; i<N; ++i)
{
m_arr[i] = i;
}
}
inline constexpr void sum()
{
m_sum = 0;
for (int i = 0; i<N; ++i)
{
m_sum += m_arr[i];
}
}
inline constexpr int sum_res()
{
return this->m_sum;
}
private:
int m_arr[N];
int m_sum;
};
#define NUMBER (6)
int main()
{
constexpr auto res = constexpr_sum_array_compile_time<NUMBER>().sum_res();
return res;
}
现在无论我在NUMBER(甚至100000)中写什么,它都会显示在编译时优化和计算的值!
答案 0 :(得分:1)
与您的期望相反,您的课程不是constexpr
(并且未在constexpr表达中使用)。
constexpr auto res = constexpr_sum_array_compile_time<NUMBER>().sum_res();
会显示您遇到的不同错误。
所以你在装配时观察到的只是定期优化。