This is an academic question.
sdt::mutex m;
typedef std::lock_guard<std::mutex> G;
void thread1(){
G g(m);
std::cout << std::setw(9);
std::cout << 3.14;
std::cout << std::endl;
}
void thread2(){
G g(m);
std::cout << std::setw(7);
std::cout << 3.14;
std::cout << std::endl;
}
My problem is that the formatting is bound to the output stream, so I need to set all the formatting options ever invented on my thread if I want to be sure about the output I produce. Which will or will not work next year.
Is there any way to reset formatting to default without setting everything by hand?
If not, what are the good workarounds?
For example should I create and keep an std::ostringstream locally on my thread and write oss.str() to std::cout?
I've used boost for brevity but you could write your own optional and state saver.
#include <mutex>
#include <iostream>
#include <iomanip>
#include <tuple>
#include <utility>
#include <boost/io/ios_state.hpp>
#include <boost/optional.hpp>
std::mutex m;
struct save_and_lock
{
boost::optional<boost::io::ios_all_saver> saver;
std::unique_lock<std::mutex> lock;
void init(std::ostream& os)
{
lock = std::unique_lock<std::mutex>(m);
saver.emplace(os);
os.flags(std::ios_base::fmtflags(0));
}
friend std::ostream& operator<<(std::ostream& os, save_and_lock&& s)
{
s.init(os);
return os;
}
};
void thread1(){
std::cout << save_and_lock() << std::setw(9) << 3.14 << std::endl;
}
void thread2(){
std::cout << save_and_lock() << std::setw(9) << 3.14 << std::endl;
}
This will work because the evaluation order of user-defined operator << is left to right.
Related
Some background
Today I saw, in the body of a function kaboom, a local shared_ptr pointing to a *global object and, being captured by reference and its pointee returned by reference by a lambda, i.e. [&local]() -> auto& { return *local; }; this lambda was stored somehow for further use after the function kaboom returned.
As soon as I saw this, I thought the code was invoking undefined behavior. I tried to make a minimal example to support my claim, and came up with the following.
#include <iostream>
#include <memory>
#include <functional>
#include <vector>
struct Resource {
const int i{3};
};
std::shared_ptr<Resource> global = std::make_unique<Resource>();
auto getSharedStuff() {
return global;
}
std::vector<std::function<Resource&()>> actions{};
void kaboom() {
std::shared_ptr<Resource> local = getSharedStuff();
actions.push_back([&local]() -> auto& { return *local; });
}
int main() {
kaboom();
std::cout << global->i << std::endl;
std::cout << actions[0]().i << std::endl;
}
The simple fact that the 2 couts give 3 and 0 respectively is proof for me that I'm observing UB (3 is correct, and 0 could have been anything, including 3, but I've been lucky that it was not 3, so the UB is well manifest).
Good.
The code I'm curious about
But before getting there, an intermediate version of the repro above was this:
#include <iostream>
#include <memory>
#include <functional>
#include <vector>
struct Resource {
Resource(Resource const&) = delete;
Resource(Resource&&) = delete;
Resource() { std::cout << this << "'s ctor" << std::endl; }
~Resource() { std::cout << this << "'s dtor" << std::endl; }
void operator()() { std::cout << this << "'s operator()" << std::endl; }
};
std::shared_ptr<Resource> global = std::make_unique<Resource>();
auto getSharedStuff() {
return global;
}
std::vector<std::function<Resource&()>> actions{};
void kaboom() {
std::shared_ptr<Resource> local = getSharedStuff();
actions.push_back([&local]() -> auto& { return *local; });
}
int main() {
kaboom();
std::cout << "---" << std::endl;
actions[0]()();
}
which can result in this output
0xc602b0's ctor
---
0x7f0f48f7f4a0's operator()
0xc602b0's dtor
I'm kind of ok with this, as actions[0]()() is dereferencing a destroyed shared_ptr and calling operator() on the screwed up result, so I accept that this can be screwup too.
What's funny, though, is that removing std::cout << "---" << std::endl; makes UB less manifest, as the output becomes something like this:
0xce92b0's ctor
0xce92b0's operator()
0xce92b0's dtor
So my question is: how can a "simple" line as std::cout << "---" << std::endl; affect this way the manifestation of UB?
I have a function that uses boost::bind to move function evaluation into a try/catch wrapper, based on this question.
Problem is, boost::bind doesn't seem to work with SEH - and worse, it returns a garbage value, which is exactly what I don't want. Have I made a botch of it somewhere? Even stranger, the switch /EHsc or /EHa doesn't actually seem to matter to the behavior of the program. The output you get is:
Calling
-2147483648
Done.
Press any key to continue . . .
How do I even start to figure out where things have gone wrong?
#pragma once
#include <boost/function.hpp>
#include <boost/bind.hpp>
#include <iostream>
#include <windows.h>
#include <eh.h>
using boost::function;
using boost::bind;
int potato(int q)
{
double r = 0;
return q / r;
}
template<typename T>
T exception_wrapper(boost::function<T()> func)
{
try
{
std::cout << "Calling" << std::endl;
return func();
std::cout << "After Call" << std::endl;
}
catch (...) {
std::cout << "Ex Caught" << std::endl;
return 45;
}
}
void trans_func(unsigned int u, EXCEPTION_POINTERS* pExp)
{
throw std::runtime_error("huh");
}
int main()
{
int result = exception_wrapper<int>(bind(potato, 123));
std::cout << result << std::endl;
std::cout << "Done." << std::endl;
}
If we want to construct a complex string, say like this:
"I have 10 friends and 20 relations" (where 10 and 20 are values of some variables) we can do it like this:
std::ostringstream os;
os << "I have " << num_of_friends << " friends and " << num_of_relations << " relations";
std::string s = os.str();
But it is a bit too long. If in different methods in your code you need to construct compound strings many times you will have to always define an instance of std::ostringstream elsewhere.
Is there a shorter way of doing so just in one line?
I created some extra code for being able to do this:
struct OstringstreamWrapper
{
std::ostringstream os;
};
std::string ostream2string(std::basic_ostream<char> &b)
{
std::ostringstream os;
os << b;
return os.str();
}
#define CreateString(x) ostream2string(OstringstreamWrapper().os << x)
// Usage:
void foo(int num_of_friends, int num_of_relations)
{
const std::string s = CreateString("I have " << num_of_friends << " and " << num_of_relations << " relations");
}
But maybe there is simpler way in C++ 11 or in Boost?
#include <string>
#include <iostream>
#include <sstream>
template<typename T, typename... Ts>
std::string CreateString(T const& t, Ts const&... ts)
{
using expand = char[];
std::ostringstream oss;
oss << std::boolalpha << t;
(void)expand{'\0', (oss << ts, '\0')...};
return oss.str();
}
void foo(int num_of_friends, int num_of_relations)
{
std::string const s =
CreateString("I have ", num_of_friends, " and ", num_of_relations, " relations");
std::cout << s << std::endl;
}
int main()
{
foo(10, 20);
}
Online Demo
You could use Boost.Format:
#include <iostream>
#include <boost/format.hpp>
using boost::format;
int main()
{
std::cout << boost::format("I have %1% friends and %2% relations")
% num_of_friends % num_of_relations;
}
If you do
double number;
cout.precision(3)
cout<<number;
for a number like 1.23456 you get 1.234 but if the number is 1.2 you get 1.200. How to get both 1.234 and 1.2 (they are useless zeroes)? Suppose you don't know what number you have to print.
#include <iostream>
#include <iomanip>
using namespace std;
auto main() -> int
{
cout << setprecision( 4 );
cout << 1.23456 << endl; // -> "1.235"
cout << 1.2 << endl; // -> "1.2"
}
It's that simple: it's what you get by default.
C++03 lacked a manipulator for resetting to default formatting after setting fixed or scientific. However, in C++11 the defaultfloat manipulator was introduced. You can use it like this:
#include <iostream> // defaultfloat
#include <iomanip> // setprecision
using namespace std;
#ifdef __GNUC__ // Also check for version number, e.g. 4.8.2 and earlier
namespace std {
inline
auto defaultfloat( ios_base& stream )
-> ios_base&
{ stream.unsetf( ios_base::floatfield ); return stream; }
}
#endif
auto main() -> int
{
cout << "Lots of digits: " << fixed << setprecision( 16 ) << 1.2 << endl;
cout << endl;
cout << "Deault presentation:" << endl;
cout << defaultfloat;
cout << 1.234 << endl;
cout << 1.2 << endl;
}
Did you even try your own example?
Trailing zeroés are NOT printed (by default).
In fact, one usually wants (!) those zeroes (they convey information and they avoid clobbering up the output).
This is achieved by cout << std::fixed.
Unless you have used std::fixed, 1.2 will produce 1.2, NOT 1.200, even with precision higher than 2.
BTW: Precision means all digits, not just those after the dot, hence precision=3 leads to 1.23 - UNLESS you go std::fixed, then only those after the dot are counted.
You might write a manipulator to achieve your formatting:
#include <cmath>
#include <iostream>
template <typename T>
struct DecimalPrecision
{
const T& value;
const unsigned decimals;
DecimalPrecision(const T& value, unsigned decimals)
: value(value), decimals(decimals)
{}
void write(std::ostream& stream) const {
std::ios_base::fmtflags flags = stream.flags();
stream.unsetf(std::ios_base::floatfield);
std::streamsize restore
= stream.precision(std::ceil(std::log10(std::abs(value))) + decimals);
stream << value;
stream.precision(restore);
stream.flags(flags);
}
};
template <typename T>
inline DecimalPrecision<T> decimal_precision(const T& value, unsigned decimals) {
return DecimalPrecision<T>(value, decimals);
}
template <typename T>
inline std::ostream& operator << (std::ostream& stream, const DecimalPrecision<T>& value) {
value.write(stream);
return stream;
}
#include <iomanip>
int main()
{
std::cout << std::setprecision(2);
double values[] = { 12345.6789, 1.23456789, 1.2 };
for(unsigned i = 0; i < sizeof(values)/sizeof(values[0]); ++i)
std::cout
<< i << ": " << values[i] << '\n'
<< " " << decimal_precision(values[i], 2) << '\n';
}
I need a class that redirects one ostream to another ostream during the lifetime of its object. After some tinkering I came up with this:
#include <iostream>
#include <fstream>
class ScopedRedirect
{
public:
ScopedRedirect(std::ostream & inOriginal, std::ostream & inRedirect) :
mOriginal(inOriginal),
mRedirect(inRedirect)
{
mOriginal.rdbuf(mRedirect.rdbuf(mOriginal.rdbuf()));
}
~ScopedRedirect()
{
mOriginal.rdbuf(mRedirect.rdbuf(mOriginal.rdbuf()));
}
private:
ScopedRedirect(const ScopedRedirect&);
ScopedRedirect& operator=(const ScopedRedirect&);
std::ostream & mOriginal;
std::ostream & mRedirect;
};
int main()
{
std::cout << "Before redirect." << std::endl;
std::ofstream filestream("redirected.txt");
{
ScopedRedirect redirect(std::cout, filestream);
std::cout << "During redirect." << std::endl;
}
std::cout << "After redirect." << std::endl;
return 0;
}
It seems to work fine. However, it's weird that the following line is repeated in both the constructor and destructor:
mOriginal.rdbuf(mRedirect.rdbuf(mOriginal.rdbuf()));
I think it's correct, but I would like to verify with the SO community. Can you find any errors or dangers in this code?
Edit
Make non-copyable.
The reason those lines are the same is because what you're doing is swapping the buffers. (That is, you "redirect" by swapping the original buffer with the redirect buffer; restoration is the swap back.)
While this might give you the intended effect with respect to the output stream, it's not correct because the redirect stream now outputs somewhere else. To redirect means to take one stream and make it output somewhere else; note this doesn't effect that 'somewhere else'.
Your class is not a redirect; as is, it should really be named ScopedStreamSwap. For example, try this instead:
#include <iostream>
#include <fstream>
class ScopedRedirect
{
public:
ScopedRedirect(std::ostream & inOriginal, std::ostream & inRedirect) :
mOriginal(inOriginal),
mRedirect(inRedirect)
{
mOriginal.rdbuf(mRedirect.rdbuf(mOriginal.rdbuf()));
}
~ScopedRedirect()
{
mOriginal.rdbuf(mRedirect.rdbuf(mOriginal.rdbuf()));
}
private:
ScopedRedirect(const ScopedRedirect&);
ScopedRedirect& operator=(const ScopedRedirect&);
std::ostream & mOriginal;
std::ostream & mRedirect;
};
int main()
{
std::cout << "Before redirect." << std::endl;
std::ofstream filestream("redirected.txt");
{
ScopedRedirect redirect(std::cout, filestream);
std::cout << "During redirect." << std::endl;
// oops:
filestream << "also to the file, right?...nope" << std::endl;
filestream << "ah, why am i on the screen?!" << std::endl;
}
std::cout << "After redirect." << std::endl;
// in main, return 0 is implicit, if there is no return statement;
// helpful to keep in mind in snippets and short things
}
What you want is this:
#include <iostream>
#include <fstream>
class ScopedRedirect
{
public:
ScopedRedirect(std::ostream & inOriginal, std::ostream & inRedirect) :
mOriginal(inOriginal),
mOldBuffer(inOriginal.rdbuf(inRedirect.rdbuf()))
{ }
~ScopedRedirect()
{
mOriginal.rdbuf(mOldBuffer);
}
private:
ScopedRedirect(const ScopedRedirect&);
ScopedRedirect& operator=(const ScopedRedirect&);
std::ostream & mOriginal;
std::streambuf * mOldBuffer;
};
int main()
{
std::cout << "Before redirect." << std::endl;
std::ofstream filestream("redirected.txt");
{
ScopedRedirect redirect(std::cout, filestream);
std::cout << "During redirect." << std::endl;
// yay:
filestream << "also to the file, right?...yes" << std::endl;
filestream << "i am not on the screen" << std::endl;
}
std::cout << "After redirect." << std::endl;
return 0;
}