Common Mistakes

1: using namespace

Every new developer who comes to C++ always starts writing code like this:

myfirstprog.cpp

#include <iostream>

using namespace std;

It seems reasonable, and every book on learning C++ perpetrates the same mistake. The problem is the using namespace std;. In programs that are only 10 lines long (like in most books), it does not cause any problems. But as soon as your code strays to any meaningful size, it becomes an issue. The problem with teaching new developers this technique is that they are unaware of the problems it causes, so it becomes a habit for all code they write. Break this habit now before you start doing it without thinking at the top of every source file you write.

So, what are the actual issues? Please read this article: Why is using namespace std; considered bad practice? and the best Answer that explains what the problem is in detail.

We call this problem namespace pollution. The using clause pulls everything from the named namespace into the current namespace; this will cause issues if there is already code in the current namespace. Doing this in your source file is bad enough but even worse! Is doing this in your header file. The problem with doing it in a header file is that you pollute the namespace for every source file that includes your header file. If the user of the header file is unaware of this pollution, then trying to track down a sudden new issue becomes very hard.

But not doing this is causing me much more typing!

toomuch.cpp

#include <iostream>
int main()
{
    cout << "Hello World\n";

    // Now looks much longer
    std::cout << "Hello World\n";
}

If you think adding std:: as a prefix to anything in the standard namespace is a bother (you need another language), there is a solution. Only pull into the current namespace what you actually need. Also try and restrict the scope so it is as tight as possible.

short.cpp

#include <iostream>
int main()
{
    using std::cout;
    // The using clause is scoped and thus cout is only in the global namespace for
    // the scope of the main() function.
    cout << "Hello Workld\n";
}

An additional technique to shorten namespace prefixes is namespace alias. These are very useful when things are nested inside multiple namespaces (or have very long unhelpful names)

alias.cpp

#include <boost/numeric/ublas/vector.hpp>

// Here we define bnu as an alias too: boost::numeric::ublas
// We can use either as the prefix to things in that namespace;
namespace bnu = boost::numeric::ublas;

bnu::vector<double>                      data1;
boost::numeric::ublas::vector<double>    data2;

2: Prefixing identifiers with '_'

Many developers new to C++ try to learn by browsing the standard libraries and acquiring habits from what they see or incorporating conventions from their current favorite languages into their C++ code. One thing they ultimately pick up on is using '_' as a prefix for identifiers.

Though technically not wrong in all situations, the actual rules on using the '_' as an identifier prefix are nontrivial. The issue is that most identifiers with prefix '_' are reserved for use by the implementation. Thus, the compiler/linker may potentially do special things with them. You can read up on the issue here: What are the rules about using an underscore in a C++ identifier?.

3: void main()

There are only two valid declarations for main() in C++

main.cpp

// Version 1: You don't care about command line parameters.
int main()
{
}

// Version 2: You do care about command line parameters.
int main(int argc, char* argv[])
{
        // Note: The parameters names argc and argv are not required as the names.
        //       But they are so commonly defined that way that using any other
        //       names would cause experienced developers to do a double take.
        //       It is best to stick with the convention.
}

// Version 2a: You do care about command line parameters.
#include <vector>
int main(int argc, char* argv[])
{
        // If you want to convert all the command line parameters to strings.
        // This simple trick can be useful:
        std::vector<std::string>  args(argv, argv+argc);
}

Related Posts

C++ Wrapper for Socket

The last two articles examined the "C Socket" interface provided by the OS. In this article, I wrap this functionality in a simple C++ class to provide guaranteed closing and apply a consistent except

Read More

Common Mistakes

### 1: using namespace Every new developer who comes to C++ always starts writing code like this: #### myfirstprog.cpp ```c #include <iostream> using namespace std; ``` It seems reasonable, and e

Read More

Control Flow

So far, we have created basic programs that perform a single task without making any decisions. Most (all but the most trivial) programming languages provide decision-making constructs (Conditional B

Read More