Skip to main content

Posts

iterator tags idiom and compile-time algorithm selection

Compile-time algorithm selection can be done using function overloading and traits idiom . It is a quite useful technique in generic programming. In this technique usually a set of "selector" types are used to select one among many overloaded functions. Note that the number of parameters to these overloaded functions is same but there is a "selector" type at the end of the parameter list. A use of that technique based on standard defined iterator tags is shown here .

Use of std::bad_exception

std::bad_exception is a useful device to handle unexpected exceptions in a C++ program , which works in conjunction with unexpected_handler. unexpected_handler and terminate_handler are a traditional way of dealing with unknown exceptions. std::set_unexpected () and std::set_terminate () functions let us register custom handlers instead of standard handlers, which usually abort the program. More information can be found here . Assuming g++ 4.0.2 complies with the standard in this area, I verified that if function f() throws an exception that is not listed in its exception specification list, our custom function pointed to by the unexpected_handler is invoked if we have set one. If our custom handler rethrows whatever unknown exception caused the unexpected() to be invoked, following things happen. * If the exception specification of f() included the class std::bad_exception , unexpected() will throw an object of type std::bad_exception, and the C++ run time will search for another...

Boost C++ Idioms

This time lets take a brief look at some nifty C++ idioms in the Boost peer-reviewed libraries. We will talk about Boost Base-from-Member idiom, Boost Safe bool idiom, Boost Named External Argument idiom, Boost Non-member get() idiom, Boost Meta-function wrapper idiom, Boost Iterator pair idiom, and the Boost Mutant idiom. Boost Base-from-Member idiom This idiom is used to initialize a base class from a data-member of the derived class. It sounds contradictory to the rules of C++ language and that is the reason why this idiom is present. It basically boils down to pushing the parameter data member in a private base class and put that private base class before the dependent base class in the derivation order. A generalization of the technique can be found here . Boost Safe bool idiom Many authors have talked about the evils of type conversion functions defined in a class. Such functions allow the objects of that type to participate in nonsensical expressions. One good example is in sta...

new, delete, custom memory allocation, and exception safety

This post will hopefully push you ahead to a higher level of expertise in memory management mechanics of C++ and exception safety. Here we go... Some warm-up: Consider a function void func (T*, U*); and int main() { func (new T, new U); // line 1 } Calling the function like in line 1 is a bad idea because parameter evaluation sequence is not standard and therefore it memory allocation of second new (it could T or U) fails, we have a blatant memory leak. What to do? Lets use our silver bullet: auto_ptr! but it fails too for the same reasons. Consider a function void func (std::auto_ptr <T>, std::auto_ptr <U>); Now it is possible that, even before any auto_ptrs are constructed, new may throw or a constructor may throw and all efforts go in vain. Details can be found in Hurb Sutter's More Excetional C++: Item 20-21. So we should separate the allocation and the function call. auto_ptr <T> t1 = new T; auto_ptr <U> u1 = new U; func (t1, u1); That's no better e...

Non-Virtual Interface (NVI) idiom and the design intent

Assuming that the philosophy of Non-Virtual Interface (NVI) idiom is strictly adhered I came up with a table that summarizes the design intent in terms of access modifiers and virtuality. Strict adherence of NVI allows separation of the interface of a class into two distinct interfaces: client interface (public non-virtual) and subclass interface (protected virtual/non-virtual). Such a structure helps mitigate the Fragile Base Class (FBC) Interface problem if discipline is followed. Its only downside is a little bit of code bloat. More about this approach of resolving FBC can be found here .   non-virtual virtual but not pure pure virtual without body pure virtual with body Public Clients expect substitutability. Extension points are encapsulated.  Subclasses should stay away from this if an equivalent protected function using NVI is given. Clients expect substitutability. Extension points are visible. Subclasses can option...

Virtuality is an implementation detail !

There are many ways of achieving separation of interface from implementation: 1. Using Interface Definition Language (IDL) as in CORBA 2. Bridge Pattern (GoF) 3. Pimpl idiom 4. Handle/Body idiom 5. Envelope/Letter idiom 6. Template Method pattern (GoF) The Template Method way of achieving this is a bit tricky. It basically boils down to a few class design guidelines based on access modifiers, virtuality and language expressibility. It is also known as Non-Virtual Interface (NVI) idiom. 1. Prefer to make interfaces non-virtual, using Template Method. 2. Prefer to make virtual functions private. 3. Only if derived classes need to invoke the base implementation of a virtual function, make the virtual function protected. 4. A base class destructor should be either public and virtual, or protected and non-virtual. For more information please see: Virtuality and Virtually Yours. A few more elemental base class idioms can be found here . A comparison of the above approaches can be found ...

Forgotton friend: pointer/reference to an array

The name of an array "degenerates" into a pointer to the first element of the array. For example, int Array [10]; int *p = Array; there is a quite a bit loss of information here. Specifically, such a decay loses its type information and specifically, its dimensions. The type of Array is "An integer array of 10 integers." So we lost the word "array" and we also lost the length (10) of the array. An advantage of using pointer to an array is that this type information is retained. int (*q)[10] = &Array; It declares a pointer q to to an array of 10 integers. So whats the big deal? Compiler has this information and it is happy to let us take advantage of it. template <int p, int q, int r> int average (int (&array)[p][q][r]) { ... } main () { int q [][2][2] = { { {1, 2}, {3, 4} }, { {5, 6}, {7, 8} } }; average (a); /// This call knows the dimensions of the array. } This type information can be exploited to implement the average function using templ...

More C++ links

Danny Kalev, a former member of the C++ standards committee, posts really interesting updates about C++0x (now most likely C++09) on his blog hosted by informit.com . I particularly like this one.

Service Configurator pattern and singleton deletion

The Service Configurator pattern is about linking in additional functionality in an application dynamically by means of an API such as dlsym/dlopen provided by the OS/run-time linker. Almost all popular platforms provide this functionality. This post is about programmatically, dynamically loaded libraries (hence forth called simply library)(e.g., .DLL, .so) that contain sigletons. One of my previous posts talks about singleton deletion. If the sinlgleton in such a library is a static instance then it is not deleted untill the library is closed using appropriate API such as dlclose. This can be quite undesirable or awkward at times. All the destruction techniques based on static variables fail if you want to destroy the singleton without unloading the library. A possible variant of the singleton in such a case is given below. class Singleton { protected: Singleton (); public: static Singleton *instance () { if (instance_ == 0) instance_ = new Singleton; return instance_; } static void ...

swap using XOR

In one of my previous posts I described a few ways of swapping two numbers using xor operation in a sinlge line. The discussion is not correct or rather incomplete in the sense that the algorithm needs to be guarded by an if condition. The algorithm that exercises proper care of sequence points is as below: swap (int &a, int &b) { if (&a != &b) { a ^= b; b ^= a; a ^= b; } } It is crutial that the two number must not be located at the same address. The two numbers must have different identities. The algorithm works even though the values are the same.

Publications by C++ experts

Articles by experts are saught after the most. Therefore, here are the links to the articles written by some of my favorite authors (in no particular order). Bjarne Stroustrup Jaakko Jarvi Scott Meyers Steve Dewhurst Andrei Alexandrescu Douglas Schmidt Herb Sutter Kevlin Henney Matthew Wilson Dan Saks Robert C. Martin Chuck Allison Andrew Koenig Nathan Myers James Coplien Stan Lippman ( blog ) John Vlissides Danny Kalev Angelika Langer Christopher Diggins Thomas Becker

Ownership idioms, The Move Constructor idiom and auto_ptr

There are properties of objects that are relevant beyond mere identity of the object. One of such properties is Ownership! Who owns the object? Can you transfer the ownership? Questions like these become quite important when you are implementing Resource Acquisition Is Initialization (RAII) idiom. Tom Cargill describes [in PLoPD2] a set of ownership patterns: "Creator as a Sole Owner", "Sequence of Owners", and "Shared Ownership". Lets take a look at the idioms for each one of them. Creator as a sole owner can be simply implemented using const auto_ptr idiom by Hurb Sutter. Sequence of owners come into play when ownerships moves from one guy to the other. (a.k.a. Move Semantics). Standard auto_ptrs use move semantics. Implementation of move semantics appears to be a juicy issue as far as std::auto_ptrs are concerned. See Meyer's errata like notes on his book More Effective C++ and Sutter's GotW #25 articles. M. D. Wilson's article on Move ...

The Policy Clone idiom

Modern C++ library design is heavily based on templates. Highly reusable, flexible and extensible classes can be built using policy based class design techniques. (See "Modern C++ Design" by Andrei Alexandrescu.) Sometimes, the host class of the policies need to make an exact replica of one of its policies but instantiated with different type parameter. Unfortunately, the writer of the host class template does not know the template name to instantiate beforehand. This situation is quite analogous to the situation in the Factory Method (GoF) pattern where type of the object to be created is not known apriori and therefore, the object creation is simply delegated to the derived object. In the world of templates, although the problem is conceptually is quite similar, the mechanism to solve it is a different because we are interested in a "clone" type and not an object. The Policy Clone idiom comes handy here. A member template struct (called rebind) is used to pass a...

The singleton universe!

Singleton pattern appears to be very easy to understand because in its simplest form it can be implemented in minutes with the help of well defined language idioms. But in fact, it is one of the most complex patterns I have ever read about! If you dig around a little bit, there is a whole slew of information/articles available on this nifty pattern talking about its limitations and their solutions. Here is a collection of some of the amazing articles. The Singleton pattern - Gamma et al. To kill a Singleton - John Vlissides The Monostate pattern (The Power of One (More C++ Gems) - Steve Ball and John Crawford) Implementing Singletons (Chapter 6, Modern C++ Design) - Andrei Alexandrescu Double Checked Locking Pattern (DCLP) - Doug Schmidt C++ and the perils of DCLP - Scott Meyers, Andrei Alexandrescu DCLP is broken in Java - Bacon et al. Object Lifetime Manager pattern - Levine, Gill, and Doug Schmidt

Counted Method Chaining

I built a fun set of classes using C++ template meta-programming technique to count the number of times a member method of a class is invoked in a chain . These template classes implement a meta-programming technique called Counted Method Chaining . It counts the number of times a member function is called at compile-time and does not let programmer invoke it more than a used defiend limit. The limit is passed as a integer template parameter to the class to which to method belongs. It gives a compile time error only when method chaining is used. Otherwise it throws and exception. These set of classes use the C++ technique of co-variant return types. /// @brief A genereral case of the template where add function /// is public and therefore, it can be invoked. template <unsigned int C> class Base : public Base <C-1> { public: virtual Base <C-1> & add (void const *, size_t length) = 0; }; /// @brief The special case of the template when C (count) becomes ...

Template argument dependent name lookup

Puzzle: What will be the output of the following program? struct B { void foo () { printf ("B::foo"); } }; void foo () { printf("::foo"); } template <typename Base> struct Derived : public Base { void bar () { foo (); } }; int main (void) { Derived <B> d; d.bar(); return 0; } Answer: C++ compiler does not perform template argument dependent lookup because the rule is to lookup as many names as possible at the time of parsing the template the first time. It does not wait till the instantiation of it. So ::foo!

Named Parameter Idiom

I came across another C++ idiom which is "useful if a function takes a large number of mostly default-able parameters". You can check it out here. It makes use of a fairly common technique called Method Chaining. I am thinking of putting together a list of C++ idioms, which are spread across web and also the idioms from popular books.

Double Application Of Smart Pointers

In my reading, I came across a cool, little technique in C++ which allows us to invoke a pre-method and a post-method automatically when a member method of the class is called. It makes use of so called "Double Application Of Smart Pointers" (see the second bullet). This technique might be useful to implement different popular things such as pre-conditions and post-conditions, the "Monitor Object" pattern (POSA2), pointcut models in AOP, the Decorator pattern (GOF) and also the Execute-Around-Method pattern.

g++ compiler option -Weffc++

I found it quite interesting to know that g++ compiler actually provides an option (-Weffc++) which enables warnings for constructs that violate guidelines in Effective C++!! From g++ manual (man g++) == Begin == Warn about violations of the following style guidelines from Scott Meyers’ Effective C++ book: * Item 11: Define a copy constructor and an assignment operator for classes with dynamically allocated memory. * Item 12: Prefer initialization to assignment in constructors. * Item 14: Make destructors virtual in base classes. * Item 15: Have "operator=" return a reference to *this. * Item 23: Don’t try to return a reference when you must return an object. Also warn about violations of the following style guidelines from Scott Meyers’ More Effective C++ book: * Item 6: Distinguish between prefix and postfix forms of increment and decrement operators. * Item 7: Never overload "&&", "││", or ",". When s...

Generic container idioms

Developing generic containers in C++ can become complex if you want to develope truly generic containers (as much as they can get). Relaxing the requirements on type T is the key behind developing truly generic containers. There a few C++ idioms to actually achieve the "lowest denominator" possible with requirements on type T. It is easy to come up with a generic stack which requires following operations defiend on type T: a default constructor, a copy constructor, a non-throwing destructor and a copy assignment operator. But thats too much! The requirements can be reduced to the folloing list: a copy constructor and a non-throwing destructor. To achieve this, a generic container should be able to allocate uninitialized memory and invoke constructor(s) only once on each element while "initializing" them. This is possible using following two techniques: 1. operator new: void * mem = operator new (sizeof (T) * NUMBER_OF_ELEMENTS); 2. construct helper using placemen...