std::atomic<bool> and lambda - c++11

Does anybody know why this program goes into an infinite loop, instead of stopping after 5s or so?
This happens with both the latest gcc and clang compiler; does atomic_bool suffer from hte same issues as a vector of bool?
If I use atomic<int> this works fine.
#include <algorithm>
#include <memory>
#include <utility>
#include <iostream>
#include <vector>
#include <functional>
#include <future>
#include <chrono>
using namespace std;
using namespace chrono_literals;
void send_heart_beat()
{
cout << "sending heartbeat" << endl;
}
std::future<void> f;
int main()
{
std::atomic<bool> stop(false);
f = std::async(std::launch::async,[&stop]() { while(!stop) { send_heart_beat(); std::this_thread::sleep_for(1s); } });
std::this_thread::sleep_for(5s);
stop = true;
}

std::atomic<bool> stop(false);
std::future<void> f;
These two variables are in different scopes, and f's scope is longer lived than stop's scope.
f = std::async(std::launch::async,[&stop]() { while(!stop) { send_heart_beat(); std::this_thread::sleep_for(1s); } });
here we bind a reference to stop into a lambda, and then store a (copy) of that lambda into an async object which is managed by f.
When f goes out of scope, its destructor waits for the async task to finish. But because f's scope is longer lasting than stop's, we leave the scope of stop before f waits for the thread to finish.
So our thread mindlessly continues accessing stop after stop no longer exists through a dangling reference.
This results in undefined behavior; any behavior by your program is acceptable to the standard.

Related

Why including cpp makes different result

l learned "include" keyword are just copy & paste.
But including cpp file makes different compile result.
(gcc6~8 + boost1.69)
// main.cpp
#include <iostream>
// I'll move next code to why.cpp
#include <boost/archive/iterators/base64_from_binary.hpp>
#include <boost/archive/iterators/binary_from_base64.hpp>
#include <boost/archive/iterators/transform_width.hpp>
#include <boost/archive/iterators/insert_linebreaks.hpp>
#include <boost/archive/iterators/remove_whitespace.hpp>
void testFunc()
{
using namespace boost::archive::iterators;
typedef transform_width<binary_from_base64<remove_whitespace<std::string::const_iterator>>, 8, 6> ItBinaryT;
std::string input;
std::string output(ItBinaryT(input.begin()), ItBinaryT(input.end()));
}
// -----------------------------
int main()
{
return 0;
}
Above code compiled without warning.
But, I replace some code with include cpp..
// main.cpp
#include <iostream>
#include "why.cpp" // <----------
int main()
{
return 0;
}
// why.cpp - just copy&paste
#include <boost/archive/iterators/base64_from_binary.hpp>
#include <boost/archive/iterators/binary_from_base64.hpp>
#include <boost/archive/iterators/transform_width.hpp>
#include <boost/archive/iterators/insert_linebreaks.hpp>
#include <boost/archive/iterators/remove_whitespace.hpp>
void testFunc()
{
using namespace boost::archive::iterators;
typedef transform_width<binary_from_base64<remove_whitespace<std::string::const_iterator>>, 8, 6> ItBinaryT;
std::string input;
std::string output(ItBinaryT(input.begin()), ItBinaryT(input.end()));
}
It makes warning [-Wsubobject-linkage]
~~ has a field ~~ whose type uses the anonymous namespace
~~ has a base ~~ whose type uses the anonymous namespace
Please look at this link : https://wandbox.org/permlink/bw53IK2ZZP5UWMGk
What makes this difference?
Your compiler treats the main CPP file specially under the assumption that things defined in it are very unlikely to have more than one definition and so some tests for possible violation of the One Definition Rule are not done inside that file. Using #include takes you outside that file.
I would suggest just not using -Wsubobject-linkage since its logic is based on a heuristic that is not applicable to your code.

Segmentation fault because of moved promise

I've passed a promise as a reference to a thread. Afterwards, the promise was moved into a vector via std::move. This is causing a segmentation fault when the software is executed.
I reckon the reference in the thread is never updated after moving the promise? How can I pass the promise to the thread so that I can move it afterwards? Please see the following code example of my problem.
#include <iostream>
#include <thread>
#include <vector>
#include <future>
class Test {
public:
std::thread t;
std::promise<int> p;
Test(std::thread&& rt, std::promise<int>&& rp) : t(std::move(rt)), p(std::move(rp)) {}
};
int main()
{
std::vector<Test> tests;
{
auto p = std::promise<int>();
std::thread t ([&p]{
std::cout << 1;
p.set_value(1);
});
tests.push_back(Test(std::move(t), std::move(p)));
}
for(Test& mytest : tests)
{
mytest.t.join();
}
}
The promise p that the lambda holds a reference to is moved from and goes out of scope. You'll need an extra level of indirection so that the promise never moves.
auto pp = std::make_unique<std::promise<int>>();
std::thread t ([p = pp.get()] { // <--- p is a promise<int>*
std::cout << 1;
p->set_value(1);
});
This way, the promise never moves, you just move the pointer. The lambda gets a regular non-owning pointer to the promise.
See it here.
I do not have an answer to your question. At least, I have none yet. However, no other answers seem to have appeared yet and I find your question is interesting, so let's try this:
#include <iostream>
#include <thread>
#include <vector>
#include <future>
#include <memory>
class Test {
public:
std::thread t;
std::unique_ptr<std::promise<int>> pp;
Test(std::thread&& rt, std::unique_ptr<std::promise<int>>&& rpp)
: t(std::move(rt)), pp(std::move(rpp)) {}
};
int main()
{
std::vector<Test> tests;
{
auto pp = std::make_unique<std::promise<int>>();
std::thread t ([&pp]{
std::cout << 1;
pp->set_value(1);
});
tests.push_back(Test(std::move(t), std::move(pp)));
}
for(Test& mytest : tests)
{
mytest.t.join();
}
}
Do you see what I did there? I indirected ownership of the promise through a smart pointer. We know that smart pointers destruct gracefully, so the promise itself is never moved by this code, but only the pointer to the promise is moved. Yet the code still segfaults.
So are we sure that the promise is actually what is causing the segfault?
Maybe the promise is indeed causing the segfault, but now at least we have another way to attack the problem—unless you have already tried this.

SIGINT was not declared in this scope

Background
I am trying to build a sample REST api app for Rasbian running on Raspberry 3. I used cpprestsdk.
Sample contains the following header file:
#include <condition_variable>
#include <mutex>
#include <iostream>
static std::condition_variable _condition;
static std::mutex _mutex;
namespace cfx {
class InterruptHandler {
public:
static void hookSIGINT() {
signal(SIGINT, handleUserInterrupt);
}
static void handleUserInterrupt(int signal){
if (signal == SIGINT) {
std::cout << "SIGINT trapped ..." << '\n';
_condition.notify_one();
}
}
static void waitForUserInterrupt() {
std::unique_lock<std::mutex> lock { _mutex };
_condition.wait(lock);
std::cout << "user has signaled to interrup program..." << '\n';
lock.unlock();
}
};
}
Issue
When compiling on MacOS, no problem occurs.
When compiling in rasbian however, I get error: 'SIGINT' was not declared in this scope error.
It is clear that SIGINT definition - #define SIGINT 2 or similar - is not reachable when compiling on rasbian.
Question
Why I am getting this error on rasbian but not on macOS? Is it because compiler cannot locate signal.h?
I made sure that include_directories in CMakeLists.txt contains required include paths.
UPDATE
Error resolved when I manually added #include <csignal>.
You haven't included signal.h.
You're including some C++ standard library headers, and as a side effect on MacOS, these happen to include signal.h. However, that isn't specified to happen so you can't rely on it working in different implementations of those headers.
Try adding:
#include <signal.h>
at the top.
On Linux the header file to include is
#include <signal.h>
On MacOS the equivalent header file to include is
#include <csignal.h>
Depending on your OS, header files always change. They should both do the same thing though

initializer_lists of streams (C++11)

I'm trying to pass variable number of ofstreams over to a function that accepts an initializer_list but doesn't seem to work and throws all possible errors from the initializer_list structure and about how my function is with an array of ofstreams cannot be matched to any defined function.
Is it actually possible to pass a reference of ofstreams over in an initializer_list?
test.cpp
#include "extension.h"
ofstream outputFile, outputFile2;
int main(void) {
outputFile.open(("data_1.txt");
outputFile2.open("data_2.txt");
writeSomething({outputFile, outputFile2});
outputFile.close();
outputFile2.close();
}
extension.h
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <iostream>
#include <fstream>
#include <unistd.h>
#include <string.h>
#include <initializer_list>
using namespace std;
void writeSomething(initializer_list<ofstream&> args);
extension.cpp
#include "extension.h"
void writeSomething(initializer_list<ofstream&> args) {
for (auto f : args ) {
f << "hello" << endl;
}
}
clang 3.4 (trunk 194324) produces a pretty clear error message:
initializer_list:54:23: error: 'iterator' declared as a pointer to a
reference of type
'std::basic_ofstream<char> &'
typedef const _E* iterator;
So no, it is not possible. See also Error: forming pointer to reference type 'const std::pair&'… I can't understand this error.
(gcc 4.7.2 and 4.8.1 crashes on this code due to some internal compiler error. I have submitted a bugreport.)
What you could do instead is to pass a pointer instead of a reference, something like this:
#include <fstream>
#include <initializer_list>
using namespace std;
void writeSomething(initializer_list<ofstream*> args) {
for (auto f : args )
*f << "hello" << endl;
}
int main() {
ofstream outputFile("data_1.txt");
ofstream outputFile2("data_2.txt");
writeSomething({&outputFile, &outputFile2});
}
However, I would much rather use a std::vector instead. Using an initializer list for this purpose is very strange and confusing for me.

Why is this simplest C++0x code not valid?

I encountered a weird problem just now.
The source code is simple and self-evident as follows:
#include <vector>
#include <iostream>
#include <functional>
using namespace std;
using namespace std::tr1;
template<class T_>
void show_size(T_ coll)
{
cout << coll.size();
}
int main()
{
vector<int> coll;
coll.push_back(1);
show_size(ref(coll));
return 0;
}
The VC++ 2010 reports:
error C2039: 'size' : is not a member of 'std::tr1::reference_wrapper<_Ty>'
As we know, reference_wrapper can automatically convert itself to its underlying type, here is vector<int>. Why is such simple code not valid?
No it can't that's the whole point of the reference wrapper, because it doesn't decay from the reference, unless explicitly requested using .get()
Edit: don't mix up the boosts reference wrapper with the standard one, the boost one actually has implicit conversion (but the target functionality is a little bit different)

Resources