The following code should be almost a copy of what the book Functional Programming in C++ presents at the end of Chapter 6 section 1:
#include <iostream>
#include <utility>
#include <mutex>
template<typename F>
class lazy_val {
private:
F m_computation;
mutable decltype(m_computation()) m_cache;
mutable std::once_flag m_value_flag;
public:
lazy_val(F f)
: m_computation(f)
{}
operator const decltype(m_computation())& () const {
std::call_once(m_value_flag, [this](){
m_cache = m_computation();
});
return m_cache; // the execution never gets to this line
}
};
int expensive() {
std::cout << "expensive call...\n";
return 7;
}
int main() {
std::cout << "non memoized" << '\n';
std::cout << expensive() << '\n';
std::cout << expensive() << '\n';
std::cout << expensive() << '\n';
const auto expensive_memo = lazy_val(expensive);
std::cout << "memoized" << '\n';
std::cout << expensive_memo << '\n'; // crash happens here
std::cout << expensive_memo << '\n';
std::cout << expensive_memo << '\n';
}
However, when I execute it (the compilation is goes fine), I get this error:
non memoized
expensive call...
7
expensive call...
7
expensive call...
7
memoized
terminate called after throwing an instance of 'std::system_error'
what(): Unknown error -1
Aborted (core dumped)
If ignore concurrency issues and only rely on a mutable bool m_cache_initialized; initialized to false, and a if (!m_cache_initialized) { m_cache = m_computation(); m_cache_initialized = true; }, then everything works.
This makes me think that the problem is with how I use std::call_once/std::once_flag in my code. However I don't see how it is different from what is shown in the book (constructor in Listing 6.2, but without the line initializing the m_cache_initialized to false, and the rest of the class is at the bottom of page 125 and top of 126).
You must be using Linux and gcc. An "undocumented" feature of this implementation is that any C++ code that uses any thread-related stuff must be explicitly linked with -lpthread.
I reproduced your exact crash on Linux, after compiling (with -std=c++17) and linking without -lpthread. The shown code runs fine, if explicitly linked with -lpthread.
Related
I am not able to print the output on the screen.I am using cppreference side (GCC 12.1 (c++20
)) compiler, Is there any deadlock situation in below example. Is there any online compiler i can use for trying this type of examples
#include <iostream>
#include <semaphore>
#include <thread>
#include <vector>
std::vector<int> myVec{};
std::counting_semaphore<1> prepareSignal(2); // (1)
void prepareWork()
{
myVec.insert(myVec.end(), {0, 1, 0, 3});
std::cout << "Sender: Data prepared." << '\n';
prepareSignal.release(); // (2)
}
void completeWork()
{
std::cout << "Waiter: Waiting for data." << '\n';
prepareSignal.acquire(); // (3)
myVec[2] = 2;
std::cout << "Waiter: Complete the work." << '\n';
for (auto i: myVec) std::cout << i << " ";
std::cout << '\n';
}
int main()
{
std::cout << '\n';
std::thread t1(prepareWork);
std::thread t3(completeWork);
std::thread t2(completeWork);
t1.join();
t3.join();
t2.join();
std::cout << '\n';
}
There is no deadlock, but you have a race condition:
In completeWork, prepareSignal.acquire does not block the execution (Based on c++ documentation: "When the counter is zero, acquire() blocks until the counter is incremented"). In this case, the counter is set to 2, and there is no other acquire.
So the program may run completeWork earlier than prepareWork, which will execute myVec[2] = 2;. This causes undefined behavior since your vector is empty.
You can test such errors using Address Sanitizer.
See a live example here that highlights this issue by adding a 1 second sleep delay to prepareWork:
https://godbolt.org/z/YYsfq84bd
The address sanitizer output tells you exactly where the error is!
Consider this short program that I wrote:
#include <iostream>
template<bool Debug = false>
constexpr int add(const int& a, const int& b) {
if (Debug)
std::cout << __FUNCTION__ << " called on line " << __LINE__ << '\n';
return (a + b);
}
int main() {
std::cout << add(3, 7) << '\n';
std::cout << add<true>(5, 9) << '\n';
return 0;
}
It works just fine, and it gives the proper output:
10
add called on line 6
14
However, I'd like for the line number that is printed to be the line at the call site of the program which in this program should be line 12.
So how can I use __LINE__ or some other method to give me the line number from where the function was invoked?
The desired output would be:
10
add called on line 12
14
I would like for it to be generated from the function itself if possible.
-EDIT-
As a note to the reader, I'm open to any and all options but I am limited to C++17 for my current build environment and I'm using Visual Studio.
You can call it like this instead:
template<bool Debug = false>
constexpr int add(const int& a, const int& b, int loc = __LINE__) {
if (Debug)
std::cout << __FUNCTION__ << " called on line " << loc << '\n';
return (a + b);
}
int main() {
std::cout << add(3, 7) << '\n';
std::cout << add<true>(5, 9, __LINE__) << '\n';
return 0;
}
Output:
10
add called on line 14
14
Furthermore, You can define a macro to skip the third argument:
#define add_Debug(a, b) add<true>(a,b,__LINE__)
C++ 20 and beyond
With C++20, we are getting std::source_location which contains information about line number, function, file name. If your compiler supports it, you can use that. Example (tested with g++ 9.3.0). You will not need macros anymore:
#include <iostream>
#include <experimental/source_location>
using source_location = std::experimental::source_location;
template<bool Debug = false>
constexpr int add(const int& a, const int& b, source_location l = source_location::current()) {
if (Debug)
// this will print 'main' as function name
//std::cout << l.function_name() << " called on line " << l.line() << //'\n';
std::cout << source_location::current().function_name() << " called on line " << l.line() << '\n';
return (a + b);
}
int main()
{
std::cout << add(3, 7) << '\n';
std::cout << add<true>(5, 9) << '\n';
return 0;
}
Output:
10
add<true> called on line 16
14
With source_location you don't have to use macros anymore. It will correctly print the line
If you could compile your code on Linux using some recent GCC (in July 2020, that means GCC 10), you might compile with g++ -g -O -Wall then use Ian Taylor's libbacktrace (like we do in RefPerSys) since that library parses DWARF debug information.
You might either port that library to your operating system and debug info format, or find some equivalent.
Today, a cruder possibility could be to wrap some functions with macros. For example, instead of calling foo() with some void foo(void); you would have
extern void foo_at(const char*fileno, int lineno);
#define foo() foo_at(__FILE__,__LINE__);
Indeed, C++20 should add feature tests and source_location but you might need to wait a few months for a compiler supporting it. Consider compiling a recent GCC from its source code. AFAIK MinGW 64 runs on Windows (so ask permission to use it).
I'm trying to build a lambda that wraps some input functions with some pre/post actions.
My code works fine and pre/post actions get called correctly if I try to wrap a regular function/lambda.
However, when I try to apply my decorating lambda to a function that it produced before, my program crashes after complaining that the inner function was freed at some point (this is confirmed by valgrind).
What puzzles me is that the crash depends on the compiler: the code works perfectly fine with Xcode 6 clang (clang-3.6 based), but crashes on linux using clang++-3.6 and g++4.8.4.
I've made a small program that reproduces the behaviour:
#include <iostream>
#include <string>
#include <functional>
using namespace std;
typedef function<void(void)> NestedFn;
int main()
{
// Create a cfunction
auto lambdaFactory = [&](string title, NestedFn nestedFunc)
{
// title is copied to the new lambda
return [&, title]() {
cerr << "------------ START -----------" << endl;
cerr << "Inside: " << title << endl;
nestedFunc();
cerr << "------------- END ------------" << endl;
};
}
auto l1 = lambdaFactory("1", []() { cerr << "\tNest (1)" << endl; });
auto l2 = lambdaFactory("2", []() { cerr << "\tNest (2)" << endl; });
l1(); // Works ok, displays, START, 1, END
l2(); // Same here
auto dobble = lambdaFactory("Dobble", l1);
dobble(); // Display START, Inside Dobble, START,
// then crashes when trying to execute nestedFunc(), ie l1()
}
What did I get wrong in the variable scope management ? And is there any reason for this program not crashing using Apple's LLVM ?
EDIT
For the record, here is the correct lambdaFactory after the correction suggested by T.C. :
auto lambdaFactory = [&](string title, NestedFn nestedFunc)
{
return [&, title, nestedFunc]() {
cerr << "------------ START -----------" << endl;
cerr << "Inside: " << title << endl;
nestedFunc();
cerr << "------------- END ------------" << endl;
};
};
The lambda returned by a call to lambdaFactory captures nestedFunc by reference, but nestedFunc is a function argument passed by value, so it goes out of scope as soon as the call to lambdaFactory returns, resulting in a dangling reference.
And is there any reason for this program not crashing using Apple's LLVM ?
Undefined behavior is undefined. You are also likely using two different standard library implementations (libc++ on Mac/libstdc++ on linux), so there are likely differences in how everything is laid out etc.
I wrote a very simple solution however someone laughed and found a flaw as shown here http://ideone.com/IcWMEf
#include <iostream>
#include <ostream>
#include <functional>
#include <exception>
using namespace std;
// Wrong scope(failure)
class FailBlockT
{
typedef function<void()> T;
public:
T t;
FailBlockT(T t)
{
this->t=t;
}
~FailBlockT()
{
if (std::uncaught_exception())
{
t();
}
}
};
struct Test
{
~Test()
{
try
{
FailBlockT f([]()
{
cout << "failure" << endl;
});
// there is no any exception here, but "failure" is printed.
// See output below
}
catch(...)
{
cout << "some exception" << endl;
}
}
};
int main()
{
try
{
Test t;
throw 1;
}
catch(int){}
return 0;
}
In short the problem is my code looks at std::uncaught_exception(). When an exception is thrown and a normal destructor is executed. If i use scope failure there it will look at std::uncaught_exception() and think the object scope is lost due to exception rather then simply walking out of scope.
I can't think of any good solutions to differentiate leaving scope normally VS having an exception thrown IN it. Yes i know throwing is a bad idea in dtors BUT thats why I fail to notice this problem, because I never throw in exceptions.
How do I differentiate/solve this?
No exception was thrown but it thinks it has.
An exception was thrown, just not from right there.
There is no mechanism in C++11 to ask, "Was an exception thrown from code just below me, but not from code elsewhere in the call-stack?" std::uncaught_exception is doing exactly what it is supposed to do: say whether there is an exception currently in the process of being resolved at the time the function is called. And there is, so it returns true.
C++17 adds std::uncaught_exceptions (note the plural), which can be used to detect the difference. With such a tool, you can make your FailBlock object work:
template<typename Func>
class FailBlockT
{
private:
int e_count_;
T t_;
public:
FailBlockT(T t) : e_count_(std::uncaught_exceptions()), t_(t) {}
FailBlock(const FailBlock &) = delete; //The type should not be mobile.
~FailBlockT()
{
if (std::uncaught_exceptions() != e_count_)
{
t_();
}
}
};
std::uncaught_exceptions() returns the number of exceptions that are provoking stack unwinding at the time the call was made. If the number is the same during the constructor and destructor of an object (assuming it's a stack object), then the destructor is not being called due to an exception being thrown through where this type was used.
But without this tool, it, there's not much you can do to differentiate between an exception provoking the exiting of the scope rather than exiting a scope when exception unwinding just happens to be going on. So you're going to have to bite the bullet and catch the exception like everyone else.
Or just don't put this FailBlock thing in destructors. It seems to me that those should go directly into regular functions that can actually throw (and destructors should never throw). It seems to me that you're worried about a corner case that doesn't make any real sense.
I can't think of any good solutions to differentiate leaving scope normally VS having an exception thrown IN it.
Check stack_unwinding library - I have implemented scope(failure) and scope(success) features in C++.
It is based on platform specific function uncaught_exception_count. It is similar to std::uncaught_exception from standard library, but instead of boolean result it returns unsigned int showing current count of uncaught exceptions.
Currently it is tested on {Clang 3.2, GCC 3.4.6, GCC 4.1.2, GCC 4.4.6, GCC 4.4.7, MSVC2005SP1, MSVC2008SP1, MSVC2010SP1, MSVC2012} x {x32, x64}.
In C++11 folowing syntax is available:
try
{
int some_var=1;
cout << "Case #1: stack unwinding" << endl;
scope(exit)
{
cout << "exit " << some_var << endl;
++some_var;
};
scope(failure)
{
cout << "failure " << some_var << endl;
++some_var;
};
scope(success)
{
cout << "success " << some_var << endl;
++some_var;
};
throw 1;
} catch(int){}
{
int some_var=1;
cout << "Case #2: normal exit" << endl;
scope(exit)
{
cout << "exit " << some_var << endl;
++some_var;
};
scope(failure)
{
cout << "failure " << some_var << endl;
++some_var;
};
scope(success)
{
cout << "success " << some_var << endl;
++some_var;
};
}
In C++98 it is a bit more noisier:
try
{
cout << "Case #1: stack unwinding" << endl;
BOOST_SCOPE_EXIT(void) { cout << "exit" << endl; } BOOST_SCOPE_EXIT_END
SCOPE_FAILURE(void) { cout << "failure" << endl; } SCOPE_FAILURE_END
SCOPE_SUCCESS(void) { cout << "success" << endl; } SCOPE_SUCCESS_END
throw 1;
} catch(int){}
{
cout << "Case #2: normal exit" << endl;
BOOST_SCOPE_EXIT(void) { cout << "exit" << endl; } BOOST_SCOPE_EXIT_END
SCOPE_FAILURE(void) { cout << "failure" << endl; } SCOPE_FAILURE_END
SCOPE_SUCCESS(void) { cout << "success" << endl; } SCOPE_SUCCESS_END
}
Also, library has UNWINDING_AWARE_DESTRUCTOR feature. Example:
struct DestructorInClass
{
UNWINDING_AWARE_DESTRUCTOR(DestructorInClass,unwinding)
{
cout << "DestructorInClass, unwinding: "
<< ( unwinding ? "true" : "false" ) << endl;
}
};
However, there are some cases where UNWINDING_AWARE_DESTRUCTOR may give wrong results (though scope(success) and scope(failure) features are not affected by such issues).
Suppose I have a code like this:
void printHex(std::ostream& x){
x<<std::hex<<123;
}
..
int main(){
std::cout<<100; // prints 100 base 10
printHex(std::cout); //prints 123 in hex
std::cout<<73; //problem! prints 73 in hex..
}
My question is if there is any way to 'restore' the state of cout to its original one after returning from the function? (Somewhat like std::boolalpha and std::noboolalpha..) ?
Thanks.
you need to #include <iostream> or #include <ios> then when required:
std::ios_base::fmtflags f( cout.flags() );
//Your code here...
cout.flags( f );
You can put these at the beginning and end of your function, or check out this answer on how to use this with RAII.
Note that the answers presented here won't restore the full state of std::cout. For example, std::setfill will "stick" even after calling .flags(). A better solution is to use .copyfmt:
std::ios oldState(nullptr);
oldState.copyfmt(std::cout);
std::cout
<< std::hex
<< std::setw(8)
<< std::setfill('0')
<< 0xDECEA5ED
<< std::endl;
std::cout.copyfmt(oldState);
std::cout
<< std::setw(15)
<< std::left
<< "case closed"
<< std::endl;
Will print:
case closed
rather than:
case closed0000
The Boost IO Stream State Saver seems exactly what you need. :-)
Example based on your code snippet:
void printHex(std::ostream& x) {
boost::io::ios_flags_saver ifs(x);
x << std::hex << 123;
}
I've created an RAII class using the example code from this answer. The big advantage to this technique comes if you have multiple return paths from a function that sets flags on an iostream. Whichever return path is used, the destructor will always be called and the flags will always get reset. There is no chance of forgetting to restore the flags when the function returns.
class IosFlagSaver {
public:
explicit IosFlagSaver(std::ostream& _ios):
ios(_ios),
f(_ios.flags()) {
}
~IosFlagSaver() {
ios.flags(f);
}
IosFlagSaver(const IosFlagSaver &rhs) = delete;
IosFlagSaver& operator= (const IosFlagSaver& rhs) = delete;
private:
std::ostream& ios;
std::ios::fmtflags f;
};
You would then use it by creating a local instance of IosFlagSaver whenever you wanted to save the current flag state. When this instance goes out of scope, the flag state will be restored.
void f(int i) {
IosFlagSaver iosfs(std::cout);
std::cout << i << " " << std::hex << i << " ";
if (i < 100) {
std::cout << std::endl;
return;
}
std::cout << std::oct << i << std::endl;
}
You can create another wrapper around the stdout buffer:
#include <iostream>
#include <iomanip>
int main() {
int x = 76;
std::ostream hexcout (std::cout.rdbuf());
hexcout << std::hex;
std::cout << x << "\n"; // still "76"
hexcout << x << "\n"; // "4c"
}
In a function:
void print(std::ostream& os) {
std::ostream copy (os.rdbuf());
copy << std::hex;
copy << 123;
}
Of course if performance is an issue this is a bit more expensive because it's copying the entire ios object (but not the buffer) including some stuff that you're paying for but unlikely to use such as the locale.
Otherwise I feel like if you're going to use .flags() it's better to be consistent and use .setf() as well rather than the << syntax (pure question of style).
void print(std::ostream& os) {
std::ios::fmtflags os_flags (os.flags());
os.setf(std::ios::hex);
os << 123;
os.flags(os_flags);
}
As others have said you can put the above (and .precision() and .fill(), but typically not the locale and words-related stuff that is usually not going to be modified and is heavier) in a class for convenience and to make it exception-safe; the constructor should accept std::ios&.
C++20 std::format will be a superior alternative to save restore in most cases
Once you can use it, you will e.g. be able to write hexadecimals simply as:
#include <format>
#include <string>
int main() {
std::cout << std::format("{:x} {:#x} {}\n", 16, 17, 18);
}
Expected output:
10 0x11 18
This will therefore completely overcome the madness of modifying std::cout state.
The existing fmt library implements it for before it gets official support: https://github.com/fmtlib/fmt Install on Ubuntu 22.04:
sudo apt install libfmt-dev
Modify source to replace:
<format> with <fmt/core.h>
std::format to fmt::format
main.cpp
#include <iostream>
#include <fmt/core.h>
int main() {
std::cout << fmt::format("{:x} {:#x} {}\n", 16, 17, 18);
}
and compile and run with:
g++ -std=c++11 -o main.out main.cpp -lfmt
./main.out
Output:
10 0x11 18
Related: std::string formatting like sprintf
With a little bit of modification to make the output more readable :
void printHex(std::ostream& x) {
ios::fmtflags f(x.flags());
x << std::hex << 123 << "\n";
x.flags(f);
}
int main() {
std::cout << 100 << "\n"; // prints 100 base 10
printHex(std::cout); // prints 123 in hex
std::cout << 73 << "\n"; // problem! prints 73 in hex..
}
Instead of injecting format into cout, the << way, adopting setf and unsetf could be a cleaner solution.
void printHex(std::ostream& x){
x.setf(std::ios::hex, std::ios::basefield);
x << 123;
x.unsetf(std::ios::basefield);
}
the ios_base namespace works fine too
void printHex(std::ostream& x){
x.setf(std::ios_base::hex, std::ios_base::basefield);
x << 123;
x.unsetf(std::ios_base::basefield);
}
Reference: http://www.cplusplus.com/reference/ios/ios_base/setf/
I would like to generalize the answer from qbert220 somewhat:
#include <ios>
class IoStreamFlagsRestorer
{
public:
IoStreamFlagsRestorer(std::ios_base & ioStream)
: ioStream_(ioStream)
, flags_(ioStream_.flags())
{
}
~IoStreamFlagsRestorer()
{
ioStream_.flags(flags_);
}
private:
std::ios_base & ioStream_;
std::ios_base::fmtflags const flags_;
};
This should work for input streams and others as well.
PS: I would have liked to make this simply a comment to above answer, stackoverflow however does not allow me to do so because of missing reputation. Thus make me clutter the answers here instead of a simple comment...