Phases of Translation

I recently came across a mention about translation when reading about constexpr. Namely that the value of a constexpr objects (constexpr functions are a bit different) can be evaluated during translation. Hence the inspiration to dig a bit deeper. If you’re like me, you know about the inputs of translation and it’s final output, but what about the different steps?

To rewind, a program consist of one or more translation units which are linked together. What’s included in a translation unit? It includes a source file, its headers, and everything else added by #include directives. How we turn the raw lines of code we programmers write, into these translation units is defined in 9 “easy” steps in the standard [lex.phases / 2.2].

Step 1: The source file characters are mapped to the basic source character set.
Continue readingPhases of Translation

Same same: Covariant return types.

In this post, I want to talk about a specific feature. To set the table, it has to do with the return type of virtual functions. The compiler usually enforces that the return type of an override method match exactly the type of the base method declaration. However, there is a little leeway, with covariant return types. This is an interesting feature in C++ which isn’t supported in C#. In a nutshell, it allows the overriding method to change the return type, as long as it is a covariant return type. For example:

class Y {};
class Z : public Y {};

struct A {
   virtual Y* foo() { return new Y(); }
};
struct B : public A {
   Z* foo() { return new Z(); } // legal code. Notice the 
                                // change of return type. 
};

This follows the Liskov Substitution Principle (LSP) very nicely, since class Z IS A class A and can be substituted as such. The standard explains this in section [class.virtual / 10.3 ] paragraph 7. This is where the conditions placed on using covariant return types are outlined:

Continue readingSame same: Covariant return types.

Adaptor Containers : What’s under the hood.

C++14 outlines 3 container adaptors: stack, queue, priority_queue. They are outlined in section [container.adaptors/23.6]. If you take a look at their constructors, you’ll notice they’re implemented in terms of other containers. Hence the “adaptor” part of their name. Looking specifically at queue, the constructor has a default parameter set to a deque, but allowing the parameter to be set to another type. Here’s the declaration:

template <class T, class Container = deque <T> >
class queue;

Your first question may be:
“Why does stack use a deque as its default underlying container?”

Your second question may be:
“What other types of containers should you use?”

If we look a the usage of a queue, we expect to be able to insert elements at the back of the container, remove from the front of the container, and read from both ends of the queue. Explicitly, this means an interface supporting front(), back(), pop_front(), push_back(). Let’s look at the available sequence containers [sequences / 23.2]: array, deque, forward_list, list, vector.

Continue readingAdaptor Containers : What’s under the hood.”

Short circuits and the evaluation order of function parameters

This post isn’t about our favorite old school robot Johnny 5. So let’s start with the second part: the non defined order of evaluation of function parameters (yes, it’s non defined)

if(A(C()), B())

The compiler is free to evaluate A(), then B(), C(), or B(), then C(), then A(), etc. This could be troublesome if you expect a variable to be initialized in A() to be used in B(). The one guarantee is that C() is evaluated before A().

Another item which has some fun with the order of evaluations are the logical operators. Probably a bit of an “yeah, makes sense”, but worth the refresher.

operator || and operator && won’t necessarily evaluate all their arguments. This is known as “Short circuit evaluation”. For example:
Continue readingShort circuits and the evaluation order of function parameters

vector < bool >: What isn’t can’t be.

vector<bool> doesn’t behave like other STL containers. If you try to obtain a reference to a bool inside the container, you’ll end up with an rvalue. Probably not what you had in mind. Oddly, it IS standard compliant (more on this later). Therefore you can’t say it’s not “standard compliant” container. What it doesn’t follow is the optional sequence container operations format from table 101 in section [sequence.reqmts / 23.2.3]. This table states the format for operator [] to return a reference or a const_reference. Assuming in this case vector<T>, a reference would be a T& and a const_reference a const T&. In the case of vector<bool>, operator[] returns a “reference” which is a class (more on this later). So there you have it. vector<bool> is standards compliant, but doesn’t meet the container requirements.

Continue readingvector < bool >: What isn’t can’t be.