这是编译器错误还是我的错误? [英] Is this a compiler bug or my bug?
本文介绍了这是编译器错误还是我的错误?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
运行以下程序两次。一次使用给定的析构函数,一次使用std :: fesetround(value);从析构函数中删除。为什么我会收到不同的输出?函数add后不应该调用析构函数吗?
#include < iostream >
#include < 字符串 >
#include < cfenv >
struct raii_feround {
raii_feround(): value (std :: fegetround()){}
~raii_feround(){std :: fesetround(值跨度>); }
inline void round_up() const noexcept {std :: fesetround(FE_UPWARD); }
inline void round_down() const noexcept {std :: fesetround(FE_DOWNWARD); }
模板< typename T>
T add(T fst,T snd) const noexcept { return fst + snd; }
private :
int 值跨度>; };
float a = 1 。 1 跨度>;
float b = 1 。 2 跨度>;
float c = 0 ;
float d = 0 ;
int main(){
{
raii_feround raii;
raii.round_up();
c = raii.add(a,b);
}
{
raii_feround raii;
raii.round_down();
d = raii.add(a,b);
}
std :: cout<< c<< \ n; // 输出为:2.3
std :: cout<< d<< \ n; // 输出为:2.3或2.29999
}
解决方案
当对象超出范围时,将调用析构函数。这是在代码中的add()
调用之后。
但是舍入模式也会影响字符串转换。因此输出的差异不是由add()
操作创建的,而是打印出结果:
- 重置模式cout
使用初始模式FE_TONEAREST
- 不重置模式cout
使用FE_DOWNWARD
这是cout
神器。试试,例如
std :: cout<< std :: setprecision( 10 )<< c<< \ n;
std :: cout<< std :: setprecision( 10 )<< d<< \ n;
Run the the following program twice. Once with the given destructor and once with "std::fesetround(value);" removed from the destructor. Why do I receive different outputs? Shouldn't destructor be called after function "add"?
#include <iostream>
#include <string>
#include <cfenv>
struct raii_feround {
raii_feround() : value(std::fegetround()) { }
~raii_feround() { std::fesetround(value); }
inline void round_up () const noexcept { std::fesetround(FE_UPWARD ); }
inline void round_down() const noexcept { std::fesetround(FE_DOWNWARD); }
template<typename T>
T add(T fst, T snd) const noexcept { return fst + snd; }
private:
int value; };
float a = 1.1;
float b = 1.2;
float c = 0;
float d = 0;
int main() {
{
raii_feround raii;
raii.round_up();
c = raii.add(a, b);
}
{
raii_feround raii;
raii.round_down();
d = raii.add(a, b);
}
std::cout << c << "\n"; // Output is: 2.3
std::cout << d << "\n"; // Output is: 2.3 or 2.29999
}
What I have tried:
I ran both versions on C++ Shell
解决方案
The destructor is called when the object goes out of scope. That is after theadd()
call in your code.
But the rounding mode affects also string conversions. So the difference in the output is not created by theadd()
operations but by printing out the results:
- With resetting the modecout
uses the initial modeFE_TONEAREST
- Without resetting the modecout
usesFE_DOWNWARD
It is acout
artifact. Try, for instance
std::cout << std::setprecision(10) << c << "\n"; std::cout << std::setprecision(10) << d << "\n";
这篇关于这是编译器错误还是我的错误?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文