这是编译器错误还是我的错误? [英] Is this a compiler bug or my bug?

查看:153
本文介绍了这是编译器错误还是我的错误?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

运行以下程序两次。一次使用给定的析构函数,一次使用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
}





我尝试过:



我在 C ++ Shell

解决方案

当对象超出范围时,将调用析构函数。这是在代码中的 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 the add() call in your code.

But the rounding mode affects also string conversions. So the difference in the output is not created by the add() operations but by printing out the results:
- With resetting the mode cout uses the initial mode FE_TONEAREST
- Without resetting the mode cout uses FE_DOWNWARD


It is a cout artifact. Try, for instance

std::cout << std::setprecision(10) << c << "\n"; 
std::cout << std::setprecision(10) << d << "\n"; 


这篇关于这是编译器错误还是我的错误?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆