An Interface is More than Names and Arguments


If you claim to conform to an interface, it is not enough to follow the syntax, you must also be careful about the semantics.

I saw an example of this the other day, when I came across a custom vector class (different from std::vector) used for numerics. It provided much of the same interface provided by std::vector, among which, resize().

It looked something like this:

template <class T>
class Vec {
  (...)
  //! STL vector interface
  void resize(int size, T value);
}

That was however all the documentation that was available. Since it claimed to confirm to the stl::vector interface, I naturally assumed it meant the same thing.

Here is the documentation for std::vector::resize(size_type sz, T c):

If sz is smaller than the current vector size, the content is reduced to its first sz elements, the rest being dropped.

If sz is greater than the current vector size, the content is expanded by inserting at the end as many copies of c as needed to reach a size of sz elements.

Just to be sure, I had a look at the implementation of Vec::resize(int size, T value), and what do you know:

template <class T>
  //What was going on, conceptually:
  void Vec::resize(int size, T value) {
    _v.resize(0);
    _v.assign(size, value);
  }

See the difference? Vec::resize() drops and initializes all elements, whereas vector::resize() only initializes any extra elements. This might be dangerous if you for instance port from Vec to vector and rely on all elements to be reinitialized by resize(), or if you port from vector to Vec and rely on resize() to keep your old values.

So when claiming to confirm to an interface, make sure to not only adhere to the signature, but also to the semantics.

Allow the Compiler To Do Copies for You


Whenever possible, allow the compiler to do your copies for you. After all, it may know something you don’t:

bool search_for_token(std::string& str); //Tokens must be uppercase

bool check(const std::string& str) {
  string upper(str);
  makeUppercaseInplace(upper);
  return search_for_token(upper);
}

Even though the general best practice for passing non-changing objects is by reference to const, if you need to make a copy anyway, let the compiler do the job:

bool check(std::string str) {
  makeUppercaseInplace(str);
  return do_check(str);
}

What is the difference? It looks like when check() is called, a copy is made no matter if you or the compiler does it. The difference is, when you allow the compiler to do the job, you also alow it to skip the copy if it is not strictly needed. If the compiler detects that the string you are calling check with can never be used again, it can skip the copy and give that string directly to makeUpperCaseInplace(). Example:

std::string generateString();
check(generateString());

In this situation, the compiler knows that the return value from generateString() can never be used by anyone else[1], and can reuse that object when calling check().

Compiling Boost with STLPort on Windows


I couldn’t find a concise howto on compiling Boost with STLPort on Windows, so here it is:

  1. Download Boost. I used version 1.44, I have heard people have struggled with earlier versions.
  2. In the Boost root directory, open project-config.jam. Add the following line:
    using stlport : STLPORT_VERSION : C:/PATH_TO_STLPORT/stlport : C:/PATH_TO_STLPORT/lib ;
    , substituting STLPORT_VERSION for you version of STLPort, and PATH_TO_STLPORT to you STLPort directory.
  3. Build Boost: bjam stdlib=stlport stage. If you want to build a static lib, add link=static runtime-link=static.

My setup:

  • Boost 1.44
  • STLPort 5.2.1
  • Visual Studio 2008

If you enjoyed this post, you can subscribe to my blog, or follow me on Twitter

Show Me Your Signature, and I’ll Tell You Who You Are


When you write your function signatures, you have a choice between passing values, pointers or references. You might be able to make any of them work for the compiler, but what do they tell the user?

Note that even though pointers and reference are somewhat related, and mostly communicate the same thing, they have different suggestions about ownership.

Parameters

1: Pass by value

void foo(Bar b); I need to copy your object, because I need to modify it, and you don’t want to see the change. (Except for built-in types, which are usually passed by value even though they are not modified by the function.)

2: Pass by reference/pointer

void foo(Bar& b); void foo(Bar* b); I need a reference to your object, in order to modify it, beacuse you need to see the change.

3: Pass by reference to const

void foo(const Bar& b); void foo(const Bar * b); I won’t need to modify your object, and I don’t want to pay the price of a copy.

You could argue that 1 just means I will leave your object alone, and doesn’t say anything about modification. But if you aren’t going to modify it, you should use 3, so I think 1 explicitly states that the object is going to be modified (invisibly to the caller). Unless of course the argument is a built-in type.

Return values

1: Return by value

Bar foo(); Here, take this object and do whatever you want with it, I won’t touch it again. It’s yours.

2: Return a reference

Bar& foo(); There is an object over here that you can use. Someone else might silently change it, though. By the way, I own it, and it is my responsibility to delete it. (If foo() is a non-static member function, you can usually assume that won’t happen until the object on which it is called goes out of scope. If foo() is a static function, you can usually assume this won’t happen until the program exits.)

3: Return a pointer

Bar* foo(); There is an object over here that you can use. Someone else might silently change it, though. By the way, I might delete it at any time. Or maybe that’s your responsibility, and if you don’t, you’ll have a memory leak. But I won’t tell you which one it is! You need more information to be sure, for instance the documentation. Often, you can also deduce ownership from the situation. A singleton retains ownership, a factory does not.

4: Return a reference/pointer to const

const Bar& foo(); const Bar* foo(); There is an object over here that you can use, and I promise it won’t change, even if I still own it. Rules of deletion are as in 2. The reason I don’t list the ownership issues for the pointer in this case, is that I think const is an indication that ownership is retained. If it was not, why use const at all?

A Summary of “const”, Part One


Over the last two weeks, I have mentioned const a couple of times.

const is an often used keyword in C++ (though I would like to see people use it even more), and the different uses can be confusing. In this post I will try to summarize the most common uses:

Constant variables

Constant variables are simple, they cannot be changed after initialization:

const int answer = 43; //Cannot be changed  (even though I know you want to)
answer = 42; //Nope, not today.

Constant pointers

Constant pointers are a bit more involved, as the pointer can either be constant itself, point to something constant, or both, or none:

int x = 1;
const int c = 43;

const int * p1 = &c; //Non-const pointer to something const
p1 = &x; //So we can change what it points to
         //(Also note that a pointer to const can point to something non-const).

int * const p2 = &x; //Const pointer to something non-const.
p2 = c; //Not allowed, cannot change what it points to
*p2 = 2; //But can change the thing it points to

int * p3 = &c; //Cannot point to something const with a pointer to non-const
int * const p4 = &c; //Not even with a const pointer

const int * const p5 = &x; //Const ponter to something const
p5 = &c; //Cannot change what it points to
*p5 = 2; //Cannot change the thing it points to either

//And just to confuse things, it doesn't matter on which side of the type you put const, so the following are both a non-const pointer to a const int:

const int * d = &c;
int const * e = &c;
*d = 42; //Not allowed
*e = 42; //Not allowed

Const and functions

const can also be used with functions:

//Passing arguments as reference to const is a best practice, since this allows
//you to avoid copying, and still promise the caller that his object won't
//be modified.
void f(const string& s);

But there is one more use with const and functions, that is const member functions. Here, const applies to the method itself, not the parameters. A const member function promises to not modify the object on which it is called:

struct Foo {
    int getFoo() const; //Will not modify the object on which it is called
    int getMore(); //Might change the object on which it is called
};

int doFoo(const Foo& foo) {
    foo.getFoo(); //Ok
    foo.getMore(); //Not ok, cannot call non-const methods on const objects
}

Functions can also return const variables and pointers, but I’ll cover that in a follow-up where I’ll also cover operators. (Operators are in essence functions, but there is more to say about them.)

Changing the Unchangeable


Last week I asked you to please make member functions const whenever possible. But constant doesn’t always mean constant.

Declaring an object const is a way to tell the compiler that this object cannot be changed whatsoever. What you actually try to express might however be a logical immutability, that the meaning of the object should not change. That doesn’t necessarily imply that none of its member variables can be changed.

The most common example is to cache the result of an expensive operation. To expand on last weeks example:

class Whisky {
public:
  Smell smellIt() const;
  Taste tasteIt(int ml);
};

Imagine that computing the smell of the whisky is a complicated operation [1], that you don’t want to do every time someone smells it. You might want to introduce a private member to hold a cached description of the smell. This member must be possible to change, to be able to write the cached value. Computing and storing this value does however not logically modify the object, so it should be possible to do even for const objects. To allow for this, use the mutable keyword:

class Whisky {
public:
  Smell smellIt() const;
  Taste tasteIt(int ml);
private:
  mutable Smell* smell;
};

The definition of smellIt() would now look something like this:

Smell Whisky::smellIt() const {
  if (!smell)
    smell = computeSmell(); //Assume this function exists and returns a new, dynamically allocated Smell object
  return *smell;
}

Exactly how you do the caching is up to you, but if you use a simple pointer (and not for instance a shared_ptr), you must remember to delete smell in ~Whisky().

Please Make Member Functions Const Whenever Possible


When you write a member function that doesn’t modify the object it operates on, please make sure to make it const.

class Whisky {
public:
  Smell smellIt() const;
  Tase tasteIt(int ml);
};

Smelling the whisky doesn’t modify it, so I made smellIt() const. Tasting does however modify it (there is less left in the glass), so tasteIt() is not const.

Why does this matter? If someone makes a const object of the class, they might still want to call some methods on it. For instance, a good practice for a method is to take objects by reference to const. And then you will only be able to call const methods:

void describeWhisky(const Whisky& whisky) {
  std::cout << whisky.smellIt();
}

This would not be possible if smellIt() was not const. The same goes for using const_iterators and a lot of other situations, so please remember to add const whenever you can, even though it doesn’t make a differece to you then and there.

Edit: I posted a follow up, on how you can change some parts of an object, even if it is const.

Static and Dynamic Polymorphism – Siblings That Don’t Play Well Together


Static and dynamic polymorphism might sound related, but do not play well together, a fact I had to deal with l this week.

This is the situation: We have a set of worker classes, that work on a set of data classes. The worker classes can do different types of work, but the type of work is always known at compile time, so they were created using static polymorphism, aka templates.

template &lt;typenmame WorkImpl&gt;
class Worker {
...
};

WorkImpl decides the details of the work, but the algorithm is defined in Worker, and is always the same.

Those are the workers. We then have a pretty big tree of data classes. What kind of objects we need to deal with is not known until runtime, so we are using inheritance and virtual methods for these.

  A
 / \
B   C
|
D 

etc.

A has a virtual method fill() that gets passed a WorkImpl object, and fills it with data. fill() needs to be implemented in all the subclasses of A, to fill it with their special data. Bascially, what we want is to say

class A { 
  template  &lt;typename WorkImpl&gt;
  virtual fill(WorkImpl&amp; w) {...} //overridden in B, C, D etc.
};

Can you spot the problem?

Hint: When will the templated fill() methods be instantiated?

There is no way for the compiler to know that classes A-D will ever have their fill()-methods called, thus the fill()-methods will never be instantiated!

One solution to this problem is to make one version of fill() per type of WorkImpl, in each data class A-D. The body of a fill() method is independent of the type of WorkImpl, so this solution would lead to a lot of unnecessary duplication.

The solution we ended up with was creating wrapper methods that take a specific WorkImpl, and just calls fill() with that argument:

class A {
  virtual fillWrapper(OneWorkImpl&amp; w) { fill(w) };
  virtual fillWrapper(AnotherWorkImpl&amp; w) { fill(w) };
  template &lt;typename WorkImpl&gt;
  virtual fill(WorkImpl&amp; w) {...}
}

In this way we minimize code duplication, and still make sure the fill() methods are always instantiated.

Question: Can we get away with defining the wrappers in A only? And if not, when will it fail?

Answer: We can not. If we only define the wrappers in A, fill() will never be instantiated in B-D. Everything compiles and links, but at runtime, it is the A version that will be called for all the classes, leading to a wrong result.

Finally, I should mention that another option would have been to refactor the worker classes to use dynamic polymorphism, which would basically solve everything, and allow us to get rid of the wrapper functions. But that would have been a bigger job, which we didn’t have time for.

New Job, and Windows Survival 101


This Monday, I started in my new job at SPT Group. Their main product is OLGA, a multiphase flow simulator which has been around for thirty years, is the current clear market leader, and some say it laid the foundation for the entire Norwegian petroleum supplier industry.

This means I get to work in an advanced scientific/engineering domain, with some really smart guys, write new code, work out the intricacies of legacy code, and collaborate with both technical customers and partners like IFE. Plenty of challenges! And they seem to get a good score on the Joel Test, always a good sign.

The first challenge however, is surviving as a developer on Windows. Yes, I am now working full time in Visual Studio on a Microsoft Windows 7 workstation, which I am sure boggles the mind of people who know me well. Here’s a short survival guide:

  1. Get a decent computer. In my previous job, the main reason I tried to spend as little time in Windows as possible, was because I had a singe core laptop with 1 GB RAM, running Windows, antivirus, backup and all sorts of automated updates and configuration management software. Now add the development environment, and guess where it leaves you. My current workstation is an eight core Xenon with 8 GB RAM, and Windows feels almost as snappy as Ubuntu.
  2. Launchy is kind of like Gnome Do. You won’t have to navigate the start menu every time you want to launch a program, nor keep it in the taskbar, you just press Alt+Space, and start typing the first few letters of what you want to launch. In addition to launching applications, it can open documents and folders, act as a quick calculator, search the web, and more. It is also intelligent, so your most commonly used commands usually only needs one typed letter to launch.
  3. VirtuaWin is my favourite solution for multiple desktops on Windows. I have tested several, but this one is fast, open source and sufficiently advanced, with customizable keyboard shortcuts.
  4. AutoHotKey is a “free keyboard macro program. Supports hotkeys for keyboard, mouse, and joystick. Can expand abbreviations as you type them”. I currently just use it to fix the Windows window-manager, so you can alt+click anywhere in the window to resize it or move it around, without having to find the window border first. Here is the script I’m using for that. The tool is really much more versatile than this, for instance I once added “reload document” to the Foxit pdf-reader with a few lines of scripting.
  5. AstroGrep is a nice grepping tool. Grep is probably the command I miss most on Windows, and if you don’t want to go full CygWin, this is a quick and easy solution.
  6. gvim Update 6. Aug.: I forgot to mention vim, my trusty allround editor. I am developing in Visual Studio these days, but vim is great for other text editing as well.
  7. CygWin gives you the most common Linux tools, shells and commands. If you are used to doing a lot of ad hoc shell scripting, this is a must-have. I have used it quite a lot before, but I haven’t installed it here yet. When most of what I do goes on inside Visual Studio, the need hasn’t been there yet, AstroGrep has been enough. In projects where I do more command line stuff, I can’t live without it. Update 6 Aug.: Enough already, I miss bash, sed and awk. Installing CygWin now… Update 9 Aug.: If you decide to try out Cygwin, make sure you install a better terminal than the default Windows one, like mintty or rxvt.
  8. A good terminal Is there a good terminal for Windows, without running CygWin? I would appreciate some recommendations.

Book Review: Effective C++ by Scott Meyers


A while ago, I read Effective C++ by Scott Meyers, and I would like to recommend it.

You can read tutorials, play with the language, maybe read The C++ Programming Language by Stroustrup himself, and be able to write fully functioning C++ programs that pass all the tests, and seem to work. But still, they can have more or less subtle problems, which might manifest as random crashes, resource leaks, scalability problems, or problems with reusability and maintenance. In general, correct C++, but still wrong.

Instead of discovering all of this yourself, you can invest some time in reading best practices books. This of course goes for all languages and processes, but I think it is especially important for C++, being such a complex language, and being one of the few remaining big languages lacking a garbage collector.

Effective C++ gives you, as its full title promises, 55 Specific Ways to Improve Your Programs and Designs. These are further grouped into nine chapters that deal with related topics. Each item ranges from one page for the simple ones, to ten pages for the more involved. They all include, and tend to start with, example code, followed by a discussion of what is wrong with it, and conclude with a better way. I find this to be a good pedagogical approach, and it is indeed one I strive to follow on this blog.

Meyers start out with the simple stuff, such as recommending the use of const whenever possible. This is is simple tip by the sound of it, but he actually uses a full nine pages to cover the topic, const being such a versatile keyword. He moves on to other well known tips like preventing exceptions from leaving destructors (which I also covered briefly while elaborating on function try blocks) and keeping data members private, but also touches on more complex topics, like object oriented design in C++, the proper use of overloaded operators and keywords, and generic programming.

For a full list of chapters and items, please use the magic of the fabulous internet.

The book has four and a half stars on Amazon, which I definitely think it deserves. You do however need some experience with C++ to appreciate it, and indeed to understand some of it. I would not recommend it as follow up to a short university course about C++, or after reading an introductory text to the language, but if you have been programming C++ actively for some time, it is a rewarding read. Even if you have written C++ for many years, I am sure there is new stuff to learn in there.

If you enjoyed this post, you can subscribe to my blog, or follow me on Twitter.