我在尽我所能去理解警员。然而,我发现了一个我无法真正解释的问题(我不理解编译器对这段代码的决定)。这段代码是用X86-64 gcc 7.2上的-O3标志编译的,C++17是它的std标志(我在编译时使用了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,arr1 = 1,arr2 =2.compile_time上的arrn = n) (至少这是我希望它做的)。如果“数字”定义在范围内:{0 <=编号<= 4或8 <= NUMBER <= 71 },则该类将被完全优化,并且只返回一个值(与预期一样)。
不过!如果数字在范围内:{5 <=号码<= 7或数字>= 72},则编译器无法优化返回值。怎么会这样?这些价值观有什么特别之处?您可以在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;
}现在,无论我写什么数字(甚至100000),它都显示在编译时优化和计算的值!
发布于 2017-09-22 13:01:41
与您的预期相反,您的类不是constexpr (也不是用于constexpr表达式中)。
constexpr auto res = constexpr_sum_array_compile_time<NUMBER>().sum_res();会告诉你你有不同的错误。
所以,使用程序集所观察到的只是常规的优化。
https://stackoverflow.com/questions/46365250
复制相似问题