C++ Coding Style

Although I spent my first years at University programming in C++ and only later switched to Java, it seems that because I started my professional career with Java, it has formed my coding style a lot more than I expected. As I am writing production code using C++ now, I see quite a lot of differences in coding style and I even feel that the way I syntactically structure my code simply doesn’t feel right with C++.

There are a lot of similarities between Java and C++, they both are Object Oriented programming languages and such you create classes with methods and members. Each of these need to have a decent name, which is language independent, as a name should be short and expressive at the same time. However, I tend to write more verbose C++ code compared to Java. In this blog post we will examine the cause of this and how you can deal with it.

A first cause of verbosity is the existence of namespaces, which are present almost everywhere. Putting it in perspective, a namespace is best compared with a Java package. However in Java you only explicitly mention the package if there are multiple classes with the same name. In C++ you can do the same, but you have to explicitly mention which namespace you are using, moreover certain namespaces are pretty big (such as the standard std namespace), and it is discouraged to use the entire namespace. But even this can be resolved as you can only use parts of the namespace. So in the end this just comes down to Java doing some work automatically for you, where in C++ you have to explicitly mark it.

Just compare these snippets from C++ and Java where both create a list of strings. Note that the C++ snippet does not use the aforementioned method to make the declaration shorter.

C++Java
std::vector<std::string> fooList<String> foo

The C++ code can be made juts as short as the Java code by adding either a single ‘using namespace std’ statement or by multiple single ‘using’ statements. Both are shown in the snippet below.

#include <string>
#include <vector>

using namespace std;

using std::string;
using std::vector;

What is special in C++ is that you split up your definition and your declaration over a header file and a source file. The header file tends to look like a Java file (without the actual implementation of the methods), whereas the source file just contains the implementation of the methods. However each method has to be marked as part of the class by having the class name as a prefix separated by a double colon (as shown below).

void Foo::bar(int i) {
    ...
}

In Java, I became a big fan of finalizing as much as possible. It shows the caller that something is not possible to change, which often is a requirement when passing in arguments. I still believe in this practice, and I do this as well in C++. Again it feels like C++ makes everything a lot more verbose simply by how much you can assign to be constant. Like in Java it is possible to set variables and arguments to be constant, but C++ adds pointers and methods to that list as well. This tends to make a method signature even longer as you can see in the example below, which is the same method as the one shown before, but now with const specifiers.

void Foo::bar(const int i) const {
    ...
}

As mentioned, pointers allow for more advanced constants as well. You can not only express the pointer to be constant, but the object it points to as well. There is a big caveat here though, as the extra verbosity is simply caused by the more expressive nature of C++. In Java it is impossible to specify that the object itself can not change, you can only specify that the object being pointed to will remain the same, without any guarantee of the object content itself. I always felt this lack of expressiveness was a shortcoming of Java and actually forces you to do a lot of copies if you want to be safe.

All of this means that a single declaration will often be longer than 80, 100 or even 140 characters long. I already mentioned one way to handle this (using statements), but other possibilities exist as well. Long type definitions can be shortened by using ‘typedef’ statements. This allows you to mention the long type once, and give a shorter (and more clear) alias to it. One annoyance I have with this system is that it obfuscates the actual type, which makes it harder to find out how to instantiate the object, even more if the type is defined in another file.

typedef std::vector<std::string> StringList

StringList list;

Other more simple ways are just to stretch declarations on multiple lines. Splitting the return type, the method name and arguments over different lines will make everything longer, but more clear once you get used to it. A good editor will help here as well as it will use different colors for the method name, types and keywords which will make the distinction more clear.

const std::vector<std::string> Foo::bar(const int i, const int j) {
    ...
}

const std::vector<std::string>
Foo::bar(
    const int i,
    const int j)
{
    ...
}

Other differences that exists are caused by the users of the different languages. Where in Java everyone agrees to use camel-case to name method, in C++ the usage of underscores is very dominant. How you specify the name of the method is up to your own preference. Although I am used to using camel-case, I could see the value of using underscores especially in methods which use acronyms such as ‘getTcpConnection()’ or ‘get_tcp_connection()’.

But also the usage of the ‘m_’ prefix is still used in C++, perhaps because there is more legacy code. For new code there shouldn’t be any reason to keep on using such prefixes as a good editor will make this clear to you.

As a final remark I would like to mention that the discussion of tabs versus spaces is universal and is widely spread over all languages.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.