Previous Up Next

Chapter 5  Coding Conventions

5.1  Introduction

This chapter discusses conventions used in the source code of Config4J and Config4Cpp.

5.2  Naming Conventions

Most identifiers in Config4J and Config4Cpp are spelled using mixed capitalisation without any underscores—what is sometimes called “camel case” convention. Class names begin with an upper-case letter (for example, LexToken), while the names of operations and variables begin with a lower-case letter (for example, lookupString()). Named constants are spelled in all upper-case with underscores (for example, CFG_SCOPE, which is defined in the Configuration class).

The naming conventions discussed above should be familiar to most Java programmers. Those naming conventions are less widely used among C++ programmers, where some people prefer identifier names to consist of lower-case letters and underscores instead of camel case. I decided to use the Java naming convention in Config4Cpp to provide consistency in the public API and, to a lesser extent, implementation code.

Some minor differences in the naming conventions arise with regard to what C++ programmers call an instance (or member) variable, and what Java programmers call a field. In Config4Cpp, I use "m_" as a prefix on the names of such variables because that convention is deeply ingrained in my memory muscles. I do not use any such prefix in Config4J. If such a variable has a public accessor operation, then this is given a "get" prefix in Config4J, but not in Config4Cpp. For example, a C++ instance variable called m_foo might have an accessor operation called foo(), while the Java counterparts are called foo and getFoo().

Java requires that the name of a source-code file match the name of the class contained in it. For example, the file Foo.java contains a class called Foo. C++ does not have this same requirement, but the source-code of Config4Cpp uses that naming convention.

5.3  Use of a Single Namespace/Package

All the source code of Config4Cpp is in a single namespace. The default name of this is config4cpp, but you can change that by editing the <config4cpp/namespace.h> file. Likewise, all the source code of Config4J is in a single package. The name of this is org.config4j, but you should be able to change the package name easily by doing a global search-and-replace on the source-code files. Alternatively, an integrated development environment (IDE) might provide a “refactoring” menu option to change the package name.

Putting all the source code into a single namespace/package was done deliberately to help companies avoid a potential versioning link problem, as I now explain.

Let’s assume your company makes and sells a software library called Foo. Internally, Foo uses version p.q of Config4Cpp. One of your customers is trying to build an application that links with both the Foo library and also the Bar library (which is sold by another company). The Bar library also uses Config4Cpp internally, but, unfortunately, it uses the newer version x.y. If versions p.q and x.y of Config4Cpp are not binary compatible, then you are likely to receive technical support calls from your customer, asking you to urgently upgrade to the x.y version of Config4Cpp, so the customer can build their application without link errors.

You can avoid the need to deal with such technical support requests if you take two steps when implementing the Foo library. First, change the namespace of Config4Cpp when compiling it for use inside the Foo library. Second, if the Foo library needs to expose a configuration API to users of Foo, then do not expose the Config4Cpp API directly. Instead, look at the source code of some of the demo programs (discussed in the Config4* Getting Started Guide) to see how you can put a Foo “wrapper” API around the Config4Cpp API. If you take those two simple steps, then your customers will not encounter the linking problems discussed above.

There is, unfortunately, a price to be paid for the above advice: code bloat. In particular, your customer’s application will end up being linked with several copies of Config4Cpp (each compiled in a different namespace). At the time of writing, each copy of the Config4Cpp library will add a few hundred KB to an application. However, I think such code bloat is an acceptable price to pay when when modern computers have several GB of RAM.

5.4  Indentation and Spacing

Indentation in source-code files is with TAB characters. Please configure your text editor or integrated development environment (IDE) so that a TAB character displays as 4 spaces.1 Lines of source code should never be more than 80 columns wide.

Please do not put spaces around "(" or ")" characters when invoking a function. Also, the opening "{" in an if-then-else statement, while-loop or for-loop should not be on a separate line (unless you need to avoid line wrap).

obj.someOp ( parameter ); // bad
obj.someOP(parameter);    // good

if (someCondition)        // bad
{
    ...
}
if (someCondition) {      // good
    ...
}

1
If you use the vim text editor, then the following information may be useful. By default, vim treats a TAB character as 8 spaces. You can override this for C++ and Java files by placing the following line into the .vimrc file in the directory specified by the HOME environment variable:
autocmd FileType cpp,java setlocal tabstop=4 shiftwidth=4

Previous Up Next