Using `std::call_once` for lazy initialization - c++

Briefly, I have a class that lazily initializes one of its data members and I'd like to figure out the best way to do this in a multithreaded environment.
In more detail, my class currently looks something like this:
#include <algorithm>
#include <optional>
#include <vector>
class A_single_threaded
{
public:
bool query(const int val) const
{
// if opt_vec is not initialized, do that now
if (!(opt_vec.has_value()))
initialize_vec();
// return true if opt_vec contains val
return std::find(std::cbegin(opt_vec), std::cend(opt_vec), val) != std::cend(opt_vec);
}
private:
mutable std::optional<std::vector<int>> opt_vec;
// sets opt_vec
void initialize_vec() const;
};
initialize_vec is the only method that modifies opt_vec, and query is the only method that calls initialize_vec. opt_vec can potentially be empty after initialize_vec returns, so giving the data member std::optional type helps distinguish when it's unset and when it's set and empty. In other instances opt_vec winds up being large and initializing it is time-consuming. And since not every A_single_threaded instance will need to run query anyway, it makes sense to avoid initializing opt_vec until a user call to query makes clear that initialization is necessary.
The approach above seems OK for a single thread, but I think it isn't naturally multithread-able. The calls to opt_vec.has_value() and initialize_vec are necessarily unsynchronized, and the gap between their return times allows for a data race that I don't think can be fixed with a mutex. Instead I think the correct solution involves replacing the std::optional with std::call_once, something like the below:
#include <algorithm>
#include <mutex>
#include <vector>
class A_multi_threaded
{
public:
bool query(const int val) const
{
// if opt_vec is not initialized, do that now
std::call_once(opt_vec_flag, initialize_vec, this);
// return true if opt_vec contains val
return std::find(std::cbegin(opt_vec), std::cend(opt_vec), val) != std::cend(opt_vec);
}
private:
mutable std::vector<int> opt_vec;
mutable std::once_flag opt_vec_flag;
// sets opt_vec
void initialize_vec() const;
};
I'd appreciate answers to a couple of questions:
Is the implementation I sketched for A_multi_threaded actually thread-safe?
Will A_multi_threaded have the same behavior as A_single_threaded in a single-threaded environment?
Is there a sensible implementation of A_multi_threaded that mimics the implementation of A_single_threaded?

Related

C++ std::atomic for user defined data types

I am unable to understand and write up a code related to below Atomic Library functionality for user defined data type:
std::atomic::compare_exchange_weak,
std::atomic::compare_exchange_strong
bool compare_exchange_weak( T& expected, T desired,
std::memory_order success,
std::memory_order failure );
bool compare_exchange_strong( T& expected, T desired,
std::memory_order success,
std::memory_order failure );
So if I have below trivial class how can I use compare_exchange_weak / compare_exchange_strong Atomic library methods on that trivial class?
class A
{
public:
void Show()
{
std::cout << "Called\n";
}
};
I am unsure what expected / desired values we should set in the method for user defined datatype - class A for example?
Your class has no data, hence there is no need to use std::atomic<A>. If you want to know how to use std::atomic with UDT, You may add a member data and then use the following code
#include <iostream>
#include <atomic>
class A
{
public:
int a;
void Show()
{
std::cout << a << "\n";
}
};
int main( ) {
A a1{1};
A a2{2};
std::atomic<A> atomicA{a1};
atomicA.load().Show();//the original atomicA
atomicA.compare_exchange_strong(a2, A{2});// this makes no change
atomicA.load().Show();
atomicA.compare_exchange_strong(a1, A{2});//this changes atomicA
atomicA.load().Show();
}
Note that not all UDT can gain a real atomic behavior (it may be achieved using locks). to make sure that your atomic has a real atomic behavior you can use atomicA.is_lock_free().

priority queue of unique_ptr comparator

i have a priority queue that stores shared_ptr<obj>. in these obj's there is a method that returns a certain value e.g obj.method1() would return an int. I want to order the queue in ascending order of this value. I tried writing a compare class in the same file but when i add it in as the 3rd parameter it says use of undeclared identifier(I don't have access to the main function that actually runs the code) I also tried using std::greater<shared_ptr<Searchable>> as the 3rd parameter, but I'm not sure if that was the write solution. any help would be appreciated.
priority_queue<shared_ptr<obj>, vector<shared_ptr<obj>>, std::greater<shared_ptr<obj>> > Q;
That is what i have right now but i dont think its working like i wanted it to
Does this work for you?
#include <memory>
#include <queue>
#include <vector>
class obj {
public:
int method1() const { return 123; }
};
using obj_ptr = std::shared_ptr<obj>;
class obj_ptr_comparator {
int operator()(const obj_ptr& lhs, const obj_ptr& rhs)
{
return lhs.get()->method1() < rhs.get()->method1();
}
};
std::priority_queue<obj_ptr, std::vector<obj_ptr>, obj_ptr_comparator> my_queue;
To clarify: The item you'll get with a my_queue.pop() will be the one with the highest value of method1() (because we're essentially running std::less, the default comparator, on the method1() value instead of the shared pointer). See also the cppreference.com entry on std::priority_queue.

Referencing AST nodes after construction with Visitor pattern

I have a memory management question. For one of my projects I am building an interpreter for a small programming language. One of the first steps is to model and build an Abstract Syntax Tree.
As of now, I'm using smart pointers to manage the lifetime of nodes, and I figured that every parent node is the owner of it's children, but it also must be shared with the environment (for example, to know which part of the tree a method's body belongs to) and with the garbage collector, which must keep a list of all references to enact the naïve mark and sweep algorithm. Therefore, I am using std::shared_ptr to keep track of the references. For instance, here's an example of a Block node, which basically represents a lambda expression:
#ifndef NAYLANG_BLOCK_H
#define NAYLANG_BLOCK_H
#include <model/ast/expressions/Expression.h>
#include <model/ast/declarations/Declaration.h>
#include <memory>
#include <vector>
namespace naylang {
#define BlockPtr std::shared_ptr<Block>
class Block : public Expression {
std::vector<std::shared_ptr<Statement>> _body;
std::vector<std::shared_ptr<Declaration>> _params;
public:
Block() = default;
void accept(Evaluator &evaluator) override;
const std::vector<std::shared_ptr<Statement>> &body() const;
const std::vector<std::shared_ptr<Declaration>> &params() const;
void addStatement(std::shared_ptr<Statement> statement);
void addParameter(std::shared_ptr<Declaration> param);
};
} // end namespace naylang
#endif //NAYLANG_BLOCK_H
As you can see, this node is the owner of all it's parameters and body expressions, and has accessors so that the Evaluator can traverse the tree.
Now, the problem comes when trying to have nodes that are bound at evaluation time to other nodes, for example:
#ifndef NAYLANG_REQUEST_H
#define NAYLANG_REQUEST_H
#include <model/ast/expressions/Expression.h>
#include <string>
#include <memory>
#include <vector>
#include <model/ast/declarations/MethodDeclaration.h>
namespace naylang {
class Request : public Expression {
std::string _name;
std::vector<ExpressionPtr> _params;
// We use naked pointers because we don't want to worry
// about memory management, and there is no ownership
// with the declaration.
const MethodDeclaration *_binding;
public:
Request(const std::string &methodName);
Request(const std::string &methodName, const std::vector<ExpressionPtr> params);
void accept(Evaluator &evaluator) override;
void bindTo(const MethodDeclaration *_binding);
const std::string &method() const;
const std::vector<ExpressionPtr> &params() const;
const MethodDeclaration &declaration() const;
};
} // end namespace naylang
#endif //NAYLANG_REQUEST_H
As you can see, bindTo() is called when a BindingEvaluator (subclass of Evaluator) evaluates a Request object, long after it's constructed. However, I am really not sure about what the _binding parameter should look like. Here's a part of the Evaluator interface:
#ifndef NAYLANG_EVALUATOR_H
#define NAYLANG_EVALUATOR_H
#include <model/ast/Statement.h>
namespace naylang {
class Request;
class Block;
class Evaluator {
public:
Evaluator() = default;
virtual ~Evaluator() = default;
// Methods left blank to be overridden by the subclasses.
// For example, a Binding Evaluator might be only interested in
// evaluating VariableReference and Request Statements
virtual void evaluate(Request &expression) {}
virtual void evaluate(Block &expression) {}
};
}
#endif //NAYLANG_EVALUATOR_H
Here's my rationale:
The reference should be polymorphic, and therefore should be some kind of pointer.
The reference does not denote ownership, and therefore it should not be a std::shared_ptr.
In addition, we need the Visitor pattern, so every node has the function void accept(Evaluator &evaluator);. As a node cannot return a shared_ptrof itself, we cannot change the interface to something like virtual void evaluate(std::shared_ptr<Request> &expression) {}.
Thus, naked pointers. I really want to get this right before moving on, because it's a ton of code to change every time I rethink it (ASTs are verbose...)
Thank you in advance.

Is a default value of nullptr in a map of pointers defined behaviour?

The following code seems to always follow the true branch.
#include <map>
#include <iostream>
class TestClass {
// implementation
}
int main() {
std::map<int, TestClass*> TestMap;
if (TestMap[203] == nullptr) {
std::cout << "true";
} else {
std::cout << "false";
}
return 0;
}
Is it defined behaviour for an uninitialized pointer to point at nullptr, or an artifact of my compiler?
If not, how can I ensure portability of the following code? Currently, I'm using similar logic to return the correct singleton instance for a log file:
#include <string>
#include <map>
class Log {
public:
static Log* get_instance(std::string path);
protected:
Log(std::string path) : path(path), log(path) {};
std::string path;
std::ostream log;
private:
static std::map<std::string, Log*> instances;
};
std::map<std::string, Log*> Log::instances = std::map<std::string, Log*>();
Log* Log::get_instance(std::string path) {
if (instances[path] == nullptr) {
instances[path] = new Log(path);
}
return instances[path];
}
One solution would be to use something similar to this where you use a special function provide a default value when checking a map. However, my understanding is that this would cause the complexity of the lookup to be O(n) instead of O(1). This isn't too much of an issue in my scenario (there would only ever be a handful of logs), but a better solution would be somehow to force pointers of type Log* to reference nullptr by default thus making the lookup check O(1) and portable at the same time. Is this possible and if so, how would I do it?
The map always value-initializes its members (in situations where they are not copy-initialized, of course), and value-initialization for builtin types means zero-initialization, therefore it is indeed defined behaviour. This is especially true for the value part of new keys generated when accessing elements with operator[] which didn't exist before calling that.
Note however that an uninizialized pointer is not necessarily a null pointer; indeed, just reading its value already invokes undefined behaviour (and might case a segmentation fault on certain platforms under certain circumstances). The point is that pointers in maps are not uninitialized. So if you write for example
void foo()
{
TestClass* p;
// ...
}
p will not be initialized to nullptr.
Note however that you might want to check for presence instead, to avoid accumulating unnecessary entries. You'd check for presence using the find member function:
map<int, TestClass*>::iterator it = TestMap.find(203);
if (it == map.end())
{
// there's no such element in the map
}
else
{
TestClass* p = it->second;
// ...
}
Yes, that's defined behaviour. If an element isn't yet in a map when you access it via operator[], it gets default constructed.

what is a good place to put a const in the following C++ statement

Consider the following class member:
std::vector<sim_mob::Lane *> IncomingLanes_;
the above container shall store the pointer to some if my Lane objects. I don't want the subroutins using this variable as argument, to be able to modify Lane objects.
At the same time, I don't know where to put 'const' keyword that does not stop me from populating the container.
could you please help me with this?
thank you and regards
vahid
Edit:
Based on the answers i got so far(Many Thanks to them all) Suppose this sample:
#include <vector>
#include<iostream>
using namespace std;
class Lane
{
private:
int a;
public:
Lane(int h):a(h){}
void setA(int a_)
{
a=a_;
}
void printLane()
{
std::cout << a << std::endl;
}
};
class B
{
public:
vector< Lane const *> IncomingLanes;
void addLane(Lane *l)
{
IncomingLanes.push_back(l);
}
};
int main()
{
Lane l1(1);
Lane l2(2);
B b;
b.addLane(&l1);
b.addLane(&l2);
b.IncomingLanes.at(1)->printLane();
b.IncomingLanes.at(1)->setA(12);
return 1;
}
What I meant was:
b.IncomingLanes.at(1)->printLane()
should work on IncomingLanes with no problem AND
b.IncomingLanes.at(1)->setA(12)
should not be allowed.(In th above example none of the two mentioned methods work!)
Beside solving the problem, I am loking for good programming practice also. So if you think there is a solution to the above problem but in a bad way, plase let us all know.
Thaks agian
A detour first: Use a smart pointer such shared_ptr and not raw pointers within your container. This would make your life a lot easy down the line.
Typically, what you are looking for is called design-const i.e. functions which do not modify their arguments. This, you achieve, by passing arguments via const-reference. Also, if it is a member function make the function const (i.e. this becomes const within the scope of this function and thus you cannot use this to write to the members).
Without knowing more about your class it would be difficult to advise you to use a container of const-references to lanes. That would make inserting lane objects difficult -- a one-time affair, possible only via initializer lists in the ctor(s).
A few must reads:
The whole of FAQ 18
Sutter on const-correctness
Edit: code sample:
#include <vector>
#include <iostream>
//using namespace std; I'd rather type the 5 characters
// This is almost redundant under the current circumstance
#include <vector>
#include <iostream>
#include <memory>
//using namespace std; I'd rather type the 5 characters
// This is almost redundant under the current circumstance
class Lane
{
private:
int a;
public:
Lane(int h):a(h){}
void setA(int a_) // do you need this?
{
a=a_;
}
void printLane() const // design-const
{
std::cout << a << std::endl;
}
};
class B
{
// be consistent with namespace qualification
std::vector< Lane const * > IncomingLanes; // don't expose impl. details
public:
void addLane(Lane const& l) // who's responsible for freeing `l'?
{
IncomingLanes.push_back(&l); // would change
}
void printLane(size_t index) const
{
#ifdef _DEBUG
IncomingLanes.at( index )->printLane();
#else
IncomingLanes[ index ]->printLane();
#endif
}
};
int main()
{
Lane l1(1);
Lane l2(2);
B b;
b.addLane(l1);
b.addLane(l2);
//b.IncomingLanes.at(1)->printLane(); // this is bad
//b.IncomingLanes.at(1)->setA(12); // this is bad
b.printLane(1);
return 1;
}
Also, as Matthieu M. suggested:
shared ownership is more complicated because it becomes difficult to
tell who really owns the object and when it will be released (and
that's on top of the performance overhead). So unique_ptr should be
the default choice, and shared_ptr a last resort.
Note that unique_ptrs may require you to move them using std::move. I am updating the example to use pointer to const Lane (a simpler interface to get started with).
You can do it this way:
std::vector<const sim_mob::Lane *> IncomingLanes_;
Or this way:
std::vector<sim_mob::Lane const *> IncomingLanes_;
In C/C++, const typename * and typename const * are identical in meaning.
Updated to address updated question:
If really all you need to do is
b.IncomingLanes.at(1)->printLane()
then you just have to declare printLane like this:
void printLane() const // Tell compiler that printLane doesn't change this
{
std::cout << a << std::endl;
}
I suspect that you want the object to be able to modify the elements (i.e., you don't want the elements to truly be const). Instead, you want nonmember functions to only get read-only access to the std::vector (i.e., you want to prohibit changes from outside the object).
As such, I wouldn't put const anywhere on IncomingLanes_. Instead, I would expose IncomingLanes_ as a pair of std::vector<sim_mob::Lane *>::const_iterators (through methods called something like GetIncomingLanesBegin() and GetIncomingLanesEnd()).
you may declare it like:
std::vector<const sim_mob::Lane *> IncomingLanes_;
you will be able to add, or remove item from array, but you want be able to change item see bellow
IncomingLanes_.push_back(someLine); // Ok
IncomingLanes_[0] = someLine; //error
IncomingLanes_[0]->some_meber = someting; //error
IncomingLanes_.erase(IncomingLanes_.end()); //OK
IncomingLanes_[0]->nonConstMethod(); //error
If you don't want other routines to modify IncomingLanes, but you do want to be able to modify it yourself, just use const in the function declarations that you call.
Or if you don't have control over the functions, when they're external, don't give them access to IncomingLanes directly. Make IncomingLanes private and provide a const getter for it.
I don't think what you want is possible without making the pointers stored in the vector const as well.
const std::vector<sim_mob::Lane*> // means the vector is const, not the pointer within it
std::vector<const sim_mob::Lane*> // means no one can modify the data pointed at.
At best, the second version does what you want but you will have this construct throughout your code where ever you do want to modify the data:
const_cast<sim_mob::Lane*>(theVector[i])->non_const_method();
Have you considered a different class hierarchy where sim_mob::Lane's public interface is const and sim_mob::Really_Lane contains the non-const interfaces. Then users of the vector cannot be sure a "Lane" object is "real" without using dynamic_cast?
Before we get to const goodness, you should first use encapsulation.
Do not expose the vector to the external world, and it will become much easier.
A weak (*) encapsulation here is sufficient:
class B {
public:
std::vector<Lane> const& getIncomingLanes() const { return incomingLanes; }
void addLane(Lane l) { incomlingLanes.push_back(l); }
private:
std::vector<Lane> incomingLanes;
};
The above is simplissime, and yet achieves the goal:
clients of the class cannot modify the vector itself
clients of the class cannot modify the vector content (Lane instances)
and of course, the class can access the vector content fully and modify it at will.
Your new main routine becomes:
int main()
{
Lane l1(1);
Lane l2(2);
B b;
b.addLane(l1);
b.addLane(l2);
b.getIncomingLanes().at(1).printLane();
b.getIncomingLanes().at(1).setA(12); // expected-error\
// { passing ‘const Lane’ as ‘this’ argument of
// ‘void Lane::setA(int)’ discards qualifiers }
return 1;
}
(*) This is weak in the sense that even though the attribute itself is not exposed, because we give a reference to it to the external world in practice clients are not really shielded.