Click here to Skip to main content
15,886,788 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
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"?

C++
#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
Posted
Updated 20-Mar-18 23:11pm

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
 
Share this answer
 
It is a cout artifact. Try, for instance
C++
std::cout << std::setprecision(10) << c << "\n"; 
std::cout << std::setprecision(10) << d << "\n"; 
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900