C++constexpr实现差异
C++ constexpr realization differencies
本文关键字:实现 C++constexpr 更新时间:2023-10-16
刚刚了解了constexpr函数,并访问godbolt了解编译器如何优化代码,发现编译器的行为截然不同。
具有以下代码:
constexpr int square(int num) {
return num * num;
}
int main() {
int a = square(2);
}
g++和icc编译器计算函数结果并将其分配给一个变量(正如我所期望的(,但msvc与clang调用函数。
要使用优化,我们应该做额外的步骤:
constexpr int square(int num) {
return num * num;
}
int main() {
constexpr int c = square(2);
int a = c;
}
对这种行为有什么合理的解释吗?
链接到导螺杆示例:https://godbolt.org/z/ez7luu
所有编译器都是正确的。
constexpr
函数是一个可以在编译时或运行时根据情况计算的函数。
假设没有"好像"规则,我们可以说,当constexpr
函数的结果到达某个被请求为已知编译时间的地方时,编译器必须计算编译时间。
例如,阵列的大小
int a[square(10)];
或模板参数
std::array<int, square(10)> a;
或constexpr
可变
constexpr int a { square(10) };
在某些情况下,函数必须在运行时计算,就像接收运行时已知的输入值一样;例如
int a;
std::cin >> a;
int b { square(a) };
否则,编译器可以选择是在编译时还是在运行时计算该值。
在您的第一个版本中
int a = square(2);
我们在编译器中可以选择区域,因为2
是已知的编译时间,所以编译器可以选择编译时间计算,但该值是为非constexpr
变量请求的,所以不需要编译时间值。
您可以看到,两个编译器正在计算编译时,另外两个编译器在运行时。通常,这种行为在很大程度上取决于优化级别。事实上,在您的示例中将-O2
添加到编译标志后,所有编译器都会产生不同的输出。
在您的第二个版本中
constexpr int c = square(2);
constexpr
变量需要square()
值,因此所有编译器都必须计算square(2)
编译时间(而且他们可以这样做,因为2
是已知编译时间的值(。
相关文章:
- 如果没有malloc,链表实现将失败
- lambda参数转换为constexpr技巧,然后获取带链接的数组
- 如何在c++中实现处理器调度模拟器
- 如何在c++中使用引用实现类似python的行为
- 实现无开销push_back的最佳方法是什么
- 多成员Constexpr结构初始化
- 条件constexpr函数
- 使用简单类型列表实现的指数编译时间.为什么
- constexpr 函数中的非文字(通过 std::is_constant_evaluated)
- Visual C++ constexpr Hints
- 如何在BST的这个简单递归实现中消除警告
- 如何确认我的constexpr表达式实际上已经在编译时执行
- C++constexpr实现差异
- 如何在 constexpr 函数中实现回退运行时
- constexpr std ::可选的可能实现
- std::experimental::可选<T>实现:Constexpr 构造函数混淆
- C++11 constexpr 字符串实现
- Constexpr查找实现
- 静态constexpr方法实现导致GCC错误
- C++11 constexpr兼容性实现