Can't modify value passed by ref in other thread - c++

I was trying to demo to a collegue why you'd better pass const references to functions doing read only operations with the following code. To my surprise it prints "It's safe!", even if I'm changing the value of the passedBool while the other thread is sleeping.
I'm trying to find out if I made a typo somewhere, if the compiler optimizes the code and passes passedBool by copy to avoid some overhead or if starting another thread creates a local copy of passedBool.
class myClass
{
public:
myClass(bool& iBool)
{
t = thread(&myClass::myMethod,this,iBool);
}
~myClass()
{
t.join();
}
private:
thread t;
void myMethod(bool& iBool)
{
this_thread::sleep_for(chrono::seconds(1));
if(iBool)
cout << "It's safe!" << endl;
else
cout << "It's NOT safe!!!" << endl;
}
};
void main()
{
bool passedBool = true;
cout << "Passing true" << endl;
myClass mmyClass(passedBool);
cout << "Changing value for false" <<endl;
passedBool = false;
cout << "Expect \"It's NOT safe!!!\"" <<endl;
}

The arguments to the thread function are moved or copied by value. If
a reference argument needs to be passed to the thread function, it has
to be wrapped (e.g. with std::ref or std::cref).
from here

Related

Questions about the ownership transfer of unique_ptr

For the following code:
#include <memory>
#include <iostream>
#include <vector>
using namespace std;
struct pm
{
pm() : a(make_unique<vector<int>>(1, 10)){};
unique_ptr<vector<int>> a;
};
struct parms
{
parms() : a(make_unique<pm>()){};
unique_ptr<pm> a;
};
class test
{
public:
test() : p(make_unique<parms>()) {}
unique_ptr<const parms> getParms()
{
return move(p);
}
void setParms(int b)
{
p->a->a->push_back(b);
}
void pp()
{
cout << p->a->a->at(0) << "\n";
}
private:
unique_ptr<parms> p;
};
int main()
{
auto t = make_unique<test>();
t->pp();
cout << t->getParms()->a->a->at(0) << "\n";
cout << (t->getParms()==nullptr) << "\n"; ;
}
t->getParms() is a nullptr after we "cout << t->getParms()->a->a->at(0) << "\n";".
If we do the same thing for the ptr,
int main()
{
auto t = make_unique<test>();
t->setParms(5);
t->pp();
auto ptr = t->getParms();
cout << ptr->a->a->at(0) << "\n";
cout << (ptr==nullptr) << "\n"; ;
}
ptr is not a nullptr.
My question is: why cout t->getParms(), then t->getParms() is a nullptr but prt is not? Is it because of the life scope of unique_ptr? Or the temporary rvalue? What's the reason behind this behavior?
Your method getParams() transfers ownership to the caller.
unique_ptr<const parms> getParms()
{
return move(p);
}
Member is moved to the return value and now the caller owns the pointee. You are not storing the returned value here:
cout << t->getParms()->a->a->at(0) << "\n";
Though, even if you did, t does not own the param anymore, hence when you ask t again:
cout << (t->getParms()==nullptr) << "\n"; ;
It doesnt know about the param anymore.
In the second example you transfer ownership from t to ptr:
auto ptr = t->getParms();
Now ptr owns the param. And you can inspect the pointer or the value as often as you like:
cout << ptr->a->a->at(0) << "\n";
cout << (ptr==nullptr) << "\n"; ;
There is no transfer of ownership in those two lines.
What's the reason behind this behavior?
The reason, as stated above, is that getParams() transfers ownership to the caller. Thats rather uncommon for a getter method. Perhaps "stealer-method" would be a better name ;). If you don't want to give up ownership (and you are certain that the pointer is a valid one) you can simply return a reference:
const parms& getParms() const { return *p; }
My question is: why cout t->getParms(), then t->getParms() is a nullptr but prt is not?
t->getParms() transfers the ownership to the caller. This sets t->p to null. Since t->p no longer owns a pointer, there is nothing to transfer when you call t->getParms() a second time.
You never transferred ownership from ptr, so it hasn't been set to null.

Is there a way to forbid a function to be called more than one time?

I'm making a terminal app just to increase my OOP skills. I have this RunApplication()function and LoginCustomer()function to make a customer log in to the application.
This code is my RunApplicationfunction:
void RunApplication(){
while (key!='q'){
printUI();
std::cin >> key;
if (key == '1'){
LoginCustomer();
}
..... // There are many other if statements but not included here since there are many and irrelevant.
and this is my LoginCustomerfunction:
void LoginCustomer(){
std::cout << "***************************" << std::endl;
std::cout << "1 ----> Show Available Cars" << std::endl;
std::cout << "2 ----> Show Available Motors" << std::endl;
std::cout << "3 ----> Show Available Trucks" << std::endl;
std::cout << "always 'l' ----> Logout" << std::endl;
std::cout << "always 'q' ----> Exit" << std::endl;
std::cout << "***************************" << std::endl;
std::cin >> key;
if (key == 'l') //if you want to go back main page which was loaded into terminal with RunApplication()
return;
else if(key == 'q')
exit(EXIT_FAILURE);
}
return; // What if I just call RunApplication() here again instead a simple return, wouldn't program be the most inefficient program ?
else if(key == 'q')
exit(EXIT_FAILURE);
My question is can I forbid a function to be called more than one time in a program(or main) ? Because if you think about it, in the LoginCustomer If you press "l" it gets you to the main page by simply ending the LoginCustomer()using returncommand. But what if I would just use RunApplication()there again instead of returncommand wouldn't be there a inefficiency in program ? So I was thinking is there any keywordto forbid a function to be called more than one time ?
My question is can I forbid a function to be called more than one time in a program(or main) ?
You can use local static variables to have a guarantee that the code is called only once.
Example:
struct FunctionObject
{
FunctionObject()
{
std::cout << "I will be called only once" << std::endl;
}
};
void Do()
{
static FunctionObject fo;
}
int main()
{
std::cout << "First" << std::endl;
Do();
std::cout << "Second" << std::endl;
Do();
}
But for your UI example I would prefer a design with simple state machine which take care that states can only be activated in a given order.
I'm making a terminal app just to increase my OOP skills.
Your example code did not have any object nor any OOP design. Maybe you have some classes/objects elsewhere, but I can't see any OOP design in your code.
You can use std::call_once: https://en.cppreference.com/w/cpp/thread/call_once
static std::once_flag flag;
std::call_once(flag, []{
//code here..
});
Local variables are stored and created on the stack. Static local variables are constant and remain between calls so:
bool my_one_off_function ()
{
static int iCount = 0; // static only intialized at start of program
if (! iCount++) // First time only will be zero
{
do_first_call_stuff ();
return true;
}
else
return false;
}
Alternatively, in your specific case, when the login request is received, you could just check if the login credentials already exist before calling the login function. This would be the more "elegant" solution because it allows logout etc.

Is it safe to call function accepting parameters by r-value reference twice with moved object?

I have the following piece of code. I expected it to fail, i.e. I thought that move constructor would execute when entering 'send' function and, when trying to call 'send' again this should be an invalid operation ('a' is no longer a valid object because it was moved from). But somehow this code executes without any problem.
Output shows that move constructor is not even executed.
#include <iostream>
using namespace std;
struct A {
int *ptr;
A() { cout << "ctor A" << endl; ptr = new int(1); }
A(A&& o) { cout << "move ctor" << endl; ptr = o.ptr; o.ptr = nullptr; }
~A() { cout << "dtor" << endl; delete ptr; }
void send() { cout << *ptr << endl; }
};
bool send(A&& a, int i)
{
if (i == 0) {
cout << "returning" << endl;
return false;
}
cout << "sending" << endl;
a.send();
return true;
}
int main()
{
A a;
if(!send(move(a),0))
send(move(a),1);
}
Output:
ctor A
returning
sending
1
dtor
However when when I change the 'send' method to accept A objects by value, the problem appears exactly how I had imagined. Move ctor is called, and when second time 'send' is called, 'a' is not valid, we have segmentation fault.
bool send(A a, int i)
{
if (i == 0) {
cout << "returning" << endl;
return false;
}
cout << "sending" << endl;
a.send();
return true;
}
Result:
ctor A
move ctor
returning
dtor
move ctor
sending
Segmentation fault
So, move constructor is only called when moved object is passed by value. Ok, I got it.
My question however is this: is it safe to declare function 'send' this way, i.e. to accept parameters by r-value reference and then call it with moved object multiple times? I know that std::move doesn't really move anything, only creates r-value reference, but anyhow: is it safe? Or, in other words, is there a guideline which says "Don't do this"?
[https://wandbox.org/permlink/R5spfEGI7WZR9lwR][1]
If you actually move the object within the send function, then you will see the behavior you expect (segmentation fault when a.send is called). For example:
bool send(A &&a, int i)
{
A b = move(a);
if (i == 0) {
cout << "returning" << endl;
return false;
}
cout << "sending" << endl;
a.send();
return true;
}

Faking constness when method is const from the outside (example: caching)

Consider the following example:
#include <iostream>
using std::endl;
using std::cout;
class my_class {
private:
int _expensive_count_operation() const {
return 10;
}
bool cached;
int last_count;
public:
my_class() { cached = false; }
int get_count() {
if (cached) {
cout << "Got count from cache." << endl;
return last_count;
}
cout << "Computing count." << endl;
last_count = _expensive_count_operation();
cached = true;
return last_count;
}
int get_const_count() const {
my_class* _this = const_cast<my_class*>(this);
if (cached) {
cout << "Got count from cache." << endl;
return last_count;
}
cout << "Computing count." << endl;
_this->last_count = _expensive_count_operation();
_this->cached = true;
return last_count;
}
};
int main() {
my_class my_object1,my_object2;
int count;
count = my_object1.get_count();
cout << "Count: " << count << endl;
count = my_object1.get_count();
cout << "Count: " << count << endl;
count = my_object2.get_const_count();
cout << "Count: " << count << endl;
count = my_object2.get_const_count();
cout << "Count: " << count << endl;
}
The use of const_cast in the get_const_count method allows you to keep the method const. Now the question is what are the dangers associated with this? And how do they compare to the dangers associated with loosing the ability to use const instances (or pointers to them) of this class? And, even better, is there a better approach?
I often find myself in this situation where I have written code that I then want to optimize using caching. The problem is that I then have to remove the const declarations and propagate that change through the rest of the code base.
I would prefer to mark all cache related attributes as mutable. The meaning of const should be that the observable state is not affected by those methods (which is what your cache should do anyway). Keep in mind that all const-methods should also be thread-safe.
For further information I recommend the blog of Herb Sutter - he wrote some stuff about const-correctness since c++11. Here is also a direct Link to a related video from Herb.
It is ONLY valid to use const_cast to remove const if the original object was NOT const. If that is always the case, it should be no problem to do this.
Although I would prefer to set last_count and cached to mutable... Because you don't really want to accidentally modify any of the other parts of the object - but you DO want to modify those in the const member function.

Passing around an object in C++ by reference [duplicate]

This question already has answers here:
What are the differences between a pointer variable and a reference variable?
(44 answers)
Closed 9 years ago.
I have objects that I put into a std::vector. Later on I need to iterate through the vector and change some member variables in the objects in each position.
I think I want to pass the object once I have it by reference to a function to operate on it, but I seem to be getting an error:
Non-const lvalue reference to type 'Object' cannot bind to a value of unrelated type 'Object *'
Here is the general gist with code between omitted:
Object* o1 = Object::createWithLocation(p.x, p.y);
v.push_back(o1);
// later on
for (int f=0; f < v.size(); f++)
{
Object* obj1 = v.at(f);
addChild(h->createLayer(obj1), 3); // add the HUD
}
createLayer is defined at:
static PlantingHUD* createLayer(Object &o);
Can anyone explain my confusion between pointers and passing by reference? Do I have to do a cast of some sort?
static PlantingHUD* createLayer(Object &o);
this method need a reference to Object as the parameter,
but your input is a pointer.
Object* obj1 = v.at(f);
addChild(h->createLayer(obj1), 3); // add the HUD
That's the problem.
void foo(Object o)
Declares a function, foo, which will begin execution with a fresh, new, instance of class 'Object' called 'o'.
This is called "passing by value", but it's more accurately 'copying' because what foo receives is it's own, personal copy of the Object instances we call foo with. When "foo" ends, the "Object o" it knew, fed and put through school, will cease to be.
void foo(Object& o)
Declares a function, foo, which will begin executing with a reference to an existing instance of an 'Object', this reference will be called 'o'. If you poke or prod it, you will be changing the original.
This is called "pass by reference".
void foo(Object* o)
Declares a function, foo, which will begin executing with a variable, called "o", containing the address of what is supposed to be an instance of "Object". If you change this variable, by doing something like "o = nullptr", it will only affect the way things look inside foo. But if you send Samuel L Jackson to the address, he can deliver furious vengance that lasts beyond the lifetime of foo.
void foo(Object*& o)
Declares a function, foo, which will begin executing with a variable called "o", which is a reference to a pointer to an instance of object o - it's like an alias, except that without compiler optimization, it's actually implemented by the compiler using a sort of pointer.
Lets try these separately.
#include <iostream>
#include <cstdint>
struct Object
{
int m_i;
void event(const char* what, const char* where)
{
std::cout <<
what<< " " << (void*)this <<
" value " << m_i <<
" via " << where <<
std::endl;
}
// Construct an object with a specific value.
Object(int i) : m_i(i)
{
event("Constructed", "Operator(int i)");
}
// This is called the copy constructor, create one object from another.
Object(const Object& rhs) : m_i(rhs.m_i)
{
event("Constructed", "Operator(const Object&)");
}
// This is how to handle Object o1, o2; o1 = o2;
Object& operator=(const Object& rhs)
{
m_i = rhs.m_i;
event("Assigned", "operator=");
return *this;
}
// Handle destruction of an instance.
~Object() { event("Destructed", "~Object"); }
};
void foo1(Object o)
{
std::cout << "Entered foo1, my o has value " << o.m_i << std::endl;
// poke our local o
o.m_i += 42;
std::cout << "I changed o.m_i, it is " << o.m_i << std::endl;
}
void foo2(Object* o)
{
std::cout << "Foo2 starts with a pointer, it's value is " << (uintptr_t)o << std::endl;
std::cout << "That's an address: " << (void*)o << std::endl;
std::cout << "m_i of o has the value " << o->m_i << std::endl;
o->m_i += 42;
std::cout << "I've changed it tho, now it's " << o->m_i << std::endl;
}
void foo3(Object& o)
{
std::cout << "foo3 begins with a reference called o, " << std::endl <<
"which is sort of like a pointer but the compiler does some magic " << std::endl <<
"and we can use it like a local concrete object. " <<
std::endl <<
"Right now o.m_i is " << o.m_i <<
std::endl;
o.m_i += 42;
std::cout << "Only now, it is " << o.m_i << std::endl;
}
void foo4(Object*& o)
{
std::cout << "foo4 begins with a reference to a pointer, " << std::endl <<
"the pointer has the value " << (uintptr_t)o << " which is " <<
(void*)o <<
std::endl <<
"But the pointer points to an Object with m_i of " << o->m_i << std::endl <<
"which we accessed with '->' because the reference is to a pointer, " <<
"not to an Object." <<
std::endl;
o->m_i += 42;
std::cout << "I poked o's m_i and now it is " << o->m_i << std::endl;
// Now for something really dastardly.
o = new Object(999);
std::cout << "I just changed the local o to point to a new object, " <<
(uintptr_t)o << " or " << (void*)o << " with m_i " << o->m_i <<
std::endl;
}
int main()
{
std::cout << "Creating our first objects." << std::endl;
Object o1(100), o2(200);
std::cout << "Calling foo1 with o1" << std::endl;
foo1(o1);
std::cout << "back in main, o1.m_i is " << o1.m_i << std::endl;
std::cout << "Calling foo2 with &o1" << std::endl;
foo2(&o1);
std::cout << "back in main, o1.m_i is " << o1.m_i << std::endl;
std::cout << "Calling foo3(o2), which looks like the way we called foo1." << std::endl;
foo3(o2);
std::cout << "back in main, o2.m_i is " << o2.m_i << std::endl;
std::cout << "Creating our pointer." << std::endl;
Object* optr;
std::cout << "Setting it to point to 'o2'" << std::endl;
optr = &o2;
std::cout << "optr now has the value " << (uintptr_t)optr <<
" which is the address " << (void*)optr <<
" which points to an Object with m_i = " << optr->m_i <<
std::endl;
foo4(optr);
std::cout << "back in main, o2 has the value " << o2.m_i << std::endl <<
"and now optr has the value " << (uintptr_t)optr << std::endl <<
"and optr->m_i is now " << optr->m_i <<
std::endl;
if (optr != &o2)
delete optr; // otherwise we'd technically be leaking memory.
return 0;
}
Live demo on ideone.com.
Passing by Value
This term confuses people early in their C++ development because, in lay terms, it sounds like this is what "Object& foo" would do.
The term "pass by value" actually arises from what the language has to do to call such a function, to value-wise copy the whole of the original object/struct onto the stack or, in the case where a copy ctor is available, forward them to a value-wise constructor and recreate a copy of the original, value-by-value.
Pass-by-value should be used for most simple cases where you do not want side-effects on the values in your current scope from the function you are calling.
bool checkWidthdrawl(Dollars balance, Dollars amountToWithdraw)
{
// it's safe for me to change "balance" here because balance is mine
}
vs
bool checkWidthdrawl(Dollars& balance, Dollars amountToWithdraw)
{
balance -= amountToWithdraw;
if (balance < 0)
std::complaint << "My account seems to be missing $" << amountToWithdraw;
}
However, passing by reference can become expensive.
struct FourK { char a[1024], b[1024], c[1024], d[1024]; }
If you pass this around by value all day, you risk blowing up your stack at some point, as well as spending daft amounts of time copying all those bytes.
void foo(int i); // Unless you need to see the changes to i, this is perfectly fine.
void foo(FourK f); // Someone should hunt you down and yell "PEANUT" in your ear.
Passing by reference
References are really a contract over the pointer system that allow the language to ensure you're really talking about a concrete instance of an object, and thus allow you to refer to a pre-existing instance of a value outside of a function.
Of course, there are ways to break this, but the language tries very, very hard to make them difficult to do. For example, try adding this to the above code:
Object& makeObjectNotWar(int i)
{
Object thisObjectGoesAway(i);
return thisObjectGoesAway /*right about now*/;
}
You can also provide callers with an assurance that the function won't have any side effects on a variable with the "const" modifier.
void fooc(const Object& o)
{
o.m_i += 42; // Error
}
You can even use that within a function as a hint to yourself (and the compiler) that you don't want to accidentally change a value, here's a case where it can provide an optimization hint to the compiler:
std::vector<int> foo;
add1000valuesTo(foo);
const size_t fooSize = foo.size();
for (size_t i = 0; i < fooSize; ++i) {
// ... stuff you're sure won't decrease foo.size()
}
Without the const fooSize
for (size_t i = 0; i < foo.size(); ++i) {
The compiler has to start by assuming that "foo.size()" could be changed at any given iteration of the loop. It can probably figure out that it doesn't, but by giving it the hint, you've saved a little compile time, possibly improved your performance, and made it easier for a human to tell exactly what behavior you expected. Downside: If your loop does actually change the size of foo, you'll find out by bug reports :(
One last thing to know about pass-by-reference is that C++ references aren't protected or "ref counted". The language only promises that a reference will be valid for the duration of its scope, so long as you don't do anything stupid like, say, call something that deletes the object.
// Author intended this function to be called
// by the owner of a Dog.
void doneWithFoo(Dog& dog)
{
Dog* deadDog = &dog;
delete deadDog;
}
Rover& Babysitter::babysitDog(Dog& rover, int hours)
{
rover.feed(FeedType::Donut);
if (rover.pooped())
doneWithDog(rover);
// ...
return rover; // I have a bad feeling about this.
}
Obviously, you're not expecting "babysitDog" to result in the dog being disposed of. But bear in mind that because we passed in a reference, it to "babysitDog" that it's also gone from the caller too, and if that was using a reference... rover's dead, Dave, dead.
As with pointers, if you're going to store references beyond the scope in which you have access to them, then you become responsible for making sure the objects being referenced stick around or that the references are removed from the container before the objects do go away.