RAII = #1 exception strategy

RAII phrasebook

Advertisements

RAII phrasebook

See [[ARM]] P 358and [[Essential C++] P199.

  • local — local nonstatic object required. See [ARM]]
  • dtor — is required.
  • stack unwinding — either by exception or normal return. Note noexcept may skip stack unwinding.
  • partial destruction — see other blog posts
  • scaffolding — see other blog posts
  • exception guarantee — RAII is the only exception guarantee
  • exception strategy — RAII is the best exception strategy
  • double-exception — what if an unhandled exception triggers unwinding but en-route a new exception is born? No good strategy.
  • == for memory management .. RAII is the #1 most important memory management technique.
  • memory leak prevention
  • smart ptr — example of RAII for memory management.

nonVirtual1() calling this->virt2() #templMethod

http://www.cs.technion.ac.il/users/yechiel/c++-faq/calling-virtuals-from-base.html has a simple sample code. Simple idea but there are complexities:

  • the given print() should never be used inside base class ctor/dtor. In general, I believe any virt2() like any virtual function behaves non-virtual in ctor/dtor.
  • superclass now depends on subclass. The FAQ author basically says this dependency is by-design. I believe this is template-method pattern.
  • pure-virtual is probably required here.

IV Q: implement op=()using copier #swap+RAII

A 2010 interviewer asked:

Q: do you know any technique to implement the assignment operator using an existing copy ctor?
A: Yes. See P100 [[c++codingStd]] and P347 [[c++cookbook]] There are multiple learning points:

  • RAII works with a class owning some heap resource.
  • RAII works with a local stack object owning a heapy thingy
  • RAII provides a much-needed exception safety. For the exception guarantee to hold, std::swap and operator delete should never throw, as echoed in my books.
  • I used to think only half the swap (i.e. transfer-in) is needed. Now I know the transfer-out on the old resource is more important. It guarantees the old resource is released even-if hitting exceptions, thanks to RAII.
  • The std::swap() trick needed here is powerful because there’s a heap pointer field. Without this field, I don’t think std::swap will be relevant.
  • self-assignment check — not required as it is rare and tolerable
  • Efficiency — considered highly efficient. The same swap-based op= is used extensively in the standard library.
  • idiomatic — this implementation of operator= for a resource-owning class is considered idiomatic, due to simplicity, safety and efficiency

http://www.geeksforgeeks.org/copy-swap-idiom-c/ shows one technique. Not sure if it’s best practice. Below is my own

C & operator=(C const & rhs){
  C localCopy(rhs); //This step is not needed for move-assignment
  std::swap(localCopy.heapResource, this->heapResource);
  return *this;
}// at end of this function, localCopy is destructed, and the original this->heapResource is deleted

C & operator=(C && rhs){ //move-assignment
  std::swap(rhs.heapResource, this->heapResource);
  return *this;
}

 

CRTP,ADL,thread_local to replace old-school

  • — thread_local variable to replace member data .. q[static thread_local ] in %%production code
  • eliminates pollution
  • — ADL  is often chosen to replace member operator and methods.. ADL #namespace
  • reduces coupling
  • –CRTP is often chosen to replace runtime binding (dynamic dispatch) of virtual function call
  • Template only
  • shaves a few clock cycles in HFT

I think both are advanced.

t_implBestPractice^t_idiom^t_c++patt^namedDesignPatt^t_c++ECT66^c++tecniq^t_workTimeSaver

  • t_c++pattern — must be a named pattern
  • t_c++idiom — must be well-established small-scale
  • t_ECT and t_c++idiom are mutually exclusive
  • t_tecniq — higher than syntaxTips, less selective than t_c++idiom or t_c++pattern but Should NOT be dumping ground
  • t_implBestPractice is like gentmp

## CRTP usageS #template Method

This blog post describes two usages of CRTP

I briefly read the excellent blog https://www.fluentcpp.com/2017/05/16/what-the-crtp-brings-to-code/. I feel CRTP is advanced for almost all the contexts I can think of. (In contrast,  I can see some “necessary” usages of SFINAE, such as the one in my little AddOrder.h)

https://stackoverflow.com/questions/262254/crtp-to-avoid-dynamic-polymorphism shows a simple [1] example of CRTP to replace virtual functions. How much efficiency improvement does it make? Questionable. I always say that if you want the lowest latency, then write selected modules in assembly language, and store it in hardware like FPGA.

[1] if there is anything simple in template meta-programming.

I have heard of several techniques to avoid virtual functions, but I believe the actual evidence (in terms of measured improvement in latency) is likely unconvincing or insignificant. Therefore, if CRTP is used to eliminate virtual function latency, then I am not sure how much value it adds.

There are other techniques to avoid “virtual”. I feel they are easier to understand than CRTP.

Sometimes CRTP is the only choice — if the virtual function needs its own template parameters, then compiler will complain that “function template can’t be virtual”. Rahul hit this complaint.

Q: for a true virtual method v1(), the derived class is not yet written when the base class is compiled. Later, Only at run time can the “system” pick the right implementation of v1(). How about CRTP?
A: base class is Not compiled ahead of the derived class. Each derived class includes a header defining the base class template.

——

Beside this “virtual-elimination” use case, CRTP has other applications (am still unfamiliar with), but if I’m asked in interviews I will only mention this one use case. One of the common “other usages” is TemplateMethod with compile time (not runtime) resolution, the 1st usage in the excellent blog . In the classic template method pattern, the “procedure” is published and finalized in the base class. Individual steps of the procedure are virtual methods, resolved at runtime. In the CRTP version, superclass methods call subclass methods, safely and cleanly. Superclass using subclass is a taboo in most contexts, but both traditional TemplateMethod and CRTP-TemplateMethod are notable exceptions.

The article didn’t clearly highlight a key point about this usage — The base class NumericalFunctions is general purpose, designed to be subclassed by anyone.  I could write a Temperature class to subclass NumericalFunctions too. This way, the code in NumericalFunctions is available for reuse.

https://github.com/tiger40490/repo1/blob/cpp1/cpp/template/CRTP_demo1.cpp is working code. Key points to remember about the code sample:

  • base-class — is a template with a dummy type “Sub”
  • derived classes — have the form “class Sub1 public Base<Sub1>”
  • the static dispatch (non-virtual) function in Base always static_cast “this” to *Sub.

 

ADL #namespace

  • “Put the function in the same namespace as the classes it operates on.” is a one-liner summary
  • If you want to write a function that needs only a class’s public interface – then that function doesn’t have to be a (static/non-static) member. The function can become a free function placed in the same name space as the class. This increases encapsulation and data hiding, and reduces coupling as only the public interface is needed.. P79 [[c++codingStd]]
  • It’s also an idiom/pattern to impress interviewers. The published experts all seem to view ADL as a library feature mainly for overloaded operators. Read cppreference and [[c++codingStd]]. I’m not interested in that usage.
  • boost seems to use a lot of ADL
  • I feel namespace loves ADL more than any other c++ feature 🙂
  • ADL is an endorsed, prized compiler feature but still with criticisms [1]. To eliminate the confusion, simply fully qualify the function call.

[1] https://stackoverflow.com/questions/8111677/what-is-argument-dependent-lookup-aka-adl-or-koenig-lookup has the best quickguide with simple examples.

https://softwareengineering.stackexchange.com/questions/274306/free-standing-functions-in-global-namespace is a short, readable discussion.

My annotations on the formal, long-winded definition — ADL governs look-up of unqualified function names in function-call expressions (including operator calls). These function names are looked up in the namespaces of their arguments in addition to the usual namespace-based lookup.

STL+smart_pointer for SQL DTO

Are there any best practice online?

Q1: Say I have a small db table of 10 columns x 100 rows. Keys are
non-unique. To cache it we want to use STL containers. What container?
%%A: multimap or list. unordered_multimap? I may start with a vector, for simplicity. Note if 2 duplicate rows aren’t 100% identical, then multimap will lose data

Q1a: search?
%A: for a map, just lookup using this->find(). For list, iterate using generic find()

Q1c: what if I have a list of keys to search?
%%A: is there an “set_intersect()” algorithm? If none, then I would write my nested iteration. Loop through the target keys, and find() on each.
A: for_each()?

Q1e: how do you hold the 10 col?
%%A: each object in container will have 10 fields. They could be 10 custom data classes or strings, ints, floats. Probably 10 smart pointers for maximum flexibility.

Q1h: what if I have other tables to cache too?
%%A: parametrize the CacheService class. CacheService class will be a wrapper of the vector. There will be other fields beside the vector.

Q1m: how about the data class? Say you have a position table and account table to cache
%%A: either inheritance or template.

pointer/itr as field: a G3 implementation pattern

common interview question.

This mega-pattern is present in 90% of java and c# classes, and also very common in c++. Important data structure classes  relying on pointer fields include vectors, strings, hashtables and most STL or boost containers.

Three common choices for a pointer member variable:

  • Raw pointer — default choice
  • shared_ptr — often a superior choice
  • char pointer, usually a c-str

In each case, we worry about

  • construction of this field
  • freeing heap memory
  • RAII
  • what if the pointee is not on heap?
  • copy control of this field
  • ownership of the pointer
  • when to return raw ptr and when to return a smart ptr

shared_ptr field offers exception safety, automatic delete, default synthesized dtor, copier, op=

 

2 simple yet concurrent singleton implementations ] c++

Both designs are thread-safe.

  1. First design is the static factory method + a static data member initialization.
  2. Second design uses a local static object, based on [[eff C++]] P 222.
template<class T>
class StaticFieldSingleton {
private:
 static StaticFieldSingleton<T> instance_; //declaration of static field
 StaticFieldSingleton() {
  cout << "StaticFieldSingleton() ctor\n";
 }
 StaticFieldSingleton(StaticFieldSingleton<T> const &);
 StaticFieldSingleton<T>& operator=(StaticFieldSingleton<T> const &);
public:
 static StaticFieldSingleton<T>& getInstance() {
  return instance_;
 }
}; 
//separate definition required on any static field
template<class T> StaticFieldSingleton<t> StaticFieldSingleton<t>
::instance_; //<---def of static field: required complexity

///////////// 2nd design uses a static local object
class SimpleSingleton {
 SimpleSingleton() {
  cout << "SimpleSingleton()\n";
 }
 SimpleSingleton(SimpleSingleton const &);
 SimpleSingleton& operator=(SimpleSingleton const &);
public:
 static SimpleSingleton& get_instance() {
  static SimpleSingleton instance;//<----- cleaner syntax
  return instance;
 }
};
int main() {
 StaticFieldSingleton<float>::getInstance();

 SimpleSingleton& ins1 = SimpleSingleton::get_instance();
 SimpleSingleton& ins2 = SimpleSingleton::get_instance();
 cout << &ins1 << endl;
 cout << &ins2 << endl;
}

 

barebones RAII smart ptr classes

If RAII and memory management is the main purpose, I feel a better word for the class template is a “capsule class”. I feel the boost implementations are too complicated and hard to modify. Here are some small but realistic implementations

[[c++FAQ]] has a one-pager RAII capsule class.

[[safe c++]] has a 2-page-short source code for a real-world capsule. Includes both ref count and scoped versions.

http://www.artima.com/cppsource/bigtwo.html introduces a very simple RAII capsule. One of the simplest yet useful smart pointers. I think the entire class needs nothing but … big3 + ctor.

A few observations —

* It’s not reliable enough if the capsule ctor can throw. For RAII to provide the ironclad guarantee, the ctor of the “capsule” class (smart ptr or not) should be simple and robust, and no-throw. If the capsule is not even locked during construction, then it offers no protection no guarantee.

* (Smart pointer always needs a copy policy) It’s meaningless unless every client “goes through” the wrapper to get to the raw pointer. Raw pointer direct access is dangerous and should be completely avoided.

* It’s meaningless without the exception risk. RAII is mostly for exceptions and programmer forgetfulness.
* It’s meaningless if there’s no need for an ironclad “guarantee“.
* It’s meaningless if there’s no need for “automatic” cleanup.
* It relies on the dtor feature. RAII relies on dtor. Smart pointer relies on dtor.
* It relies on local stack variables,but …
* It’s unusable unless the original pointer is for a heap object.
… These keywords are the heart of RAII idiom.

Given the heavy reliance on dtor, the dtor should be fairly simple. I don’t think it should be virtual.

RAII – heap alloc/deleted in separate functions

I think the standard pattern of RAII is via a local variable. When it goes out-of-scope RAII kicks in. (P199 [[Essential C++]] is authoritative…)

Let’s focus on RAII smart ptr.

Q: Now suppose a function is designed to new up an object on the heap, and pass (by several means) it out of the function. The pointee object on heap needs to be cleaned up in another method such as mymain(). So the smart ptr is not local object. How can we use RAII smart ptr for this?

1) A tested technique – in some outer function such as mymain(), declare/create the smart ptr local variable and pass it (by ref NOT by value — tested in MSVS) into the factory function, which injects the heap ptr into the smart ptr. After using it in some other function, eventually we reach the end of mymain() and the local variable goes out of scope. Exception-safe.

2) A tested technique – a global vector holding a bunch of smart pointers. From anywhere we can save a “resource pointer” into the vector. From anywhere we can also clear the vector, and those pointee objects will receive the delete call. However, there’s no automatic, fool proof clean-up because a careless developer could forget to call clear(). Also, no exception-safety.

static object initialization order #lazy singletons

Java’s lazy singleton has a close relative among C++ idioms, comparable in popularity and implementation.

Basically, local statics are initialized upon first use, exactly. Other static Objects are initialized “sometime” before main() starts. See the Item on c vs c++ in [[More eff c++]] and P222 [[EffC++]].

In real life, this’s hard to control — a known problem but with standard solutions — something like a lazy singleton. See P 170 C++FAQ. Also addressed in [[EffC++]] P221.

c++ creational patterns – return pointers always

Many creation patterns need to return pointers.

Must use pbref not pbclone, so the choice is between pointer vs reference. I feel pointer is more flexible than reference. If creation fails, we can return NULL.

eg: virtual ctor, esp. clone()
eg: factory http://login2win.blogspot.com/2008/05/c-factory-pattern.html, [[ModernC++Design]]
eg: builder http://en.wikibooks.org/wiki/C++_Programming/Code/Design_Patterns/Creational_Patterns

pimpl -> bridge pattern

My pimco interviewer (Burak?) pointed out, again, the link between pimpl and bridge pattern. Perhaps he read [[effC++]]

See other posts about pimpl.

Based on whatever little i know about c++ design patterns, i feel bridge is arguably the most powerful, colorful pattern. Here’s one variation of the pattern, featuring bridge-over-2-trees. See [[head first design patterns]] and this detailed yet simple sample code

First you need to thoroughly master the pimpl idiom. Realize the pimp classes provide a service to a client.
-> To grasp the bridge pattern, remember the client is unimportant. It’s outside our picture.
-> Next, looking at the service side of the client-service divide. Realize we have refactored a single service class into an empty public facade[1] + a private impl (therefore PIMPL) class.
-> Next realize both classes can be abstract and subclassed.
-> We end up with 2 trees i.e. 2 class hierarchies. P292Duffy
Note the field in the empty public facade should be a pointer for maximum polymorphism and easy-copy
-> We see a link between the 2 trees since the facade HasA pointer to the pimpl class.
-> That link is the bridge!

[1] imprecisely

For More flexibility, we can use factory to manufacture subclasses. Factory must return pointers to avoid slicing.

pimpl, phrasebook

pointer – the private implementation instance is held by (smart) pointer, not by reference or by value
** P76 [[c++codingStandards]] suggests boost shared_ptr

big3 – you often need to avoid the synthesized dtor, copier and op=. See P…. [[c++codingStandard]]

FCD – see other posts

encapsulate – the “private” class is free to evolve
** wrapper class vs a private class. The public methods in the wrapper class simplify delegates to the private class.[[c++succinctly]] has a complete Pimpl example showing such “delegations”

## factory functions used with STL containers

If we use “factory” to refer to any function that can create a new object, then here are some of the factory functions (including cvctor) covered in my blog or my books.

– back_inserter — always used with something_copy() functions like replace_if/replace_copy_if, count_if, remove_if/remove_copy_if … See blog
– bind2nd — used in something_if() functions like copy, remove_copy, replace_copy … See blog
– customized binary_function like “myLess”. see blog on functor-object