C++: pragma once

With both Visual C++ and GCC supporting pragma once completely, I do not see any reason to still use the include guards. Include guards were always a messy solution and I am glad that their death certificate has been written. For example, I would typically use a ALL_CAPS version of the header filename as the defined name. But then, one had to remember to change this whenever the file was renamed. Also, an include guard involved two pieces of code (the #ifndef-#define and the #endif) between which the header code was placed, again too messy and problematic.

In comparison, using #pragma once is straightforward. As a bonus, the horrendous C++ compilation time might be reduced a bit due to optimizations for pragma once by both these compilers.

Visual C++: Assert in Release Mode

Problem

In Visual C++, assertions are disabled in Release mode and enabled in Debug mode of the solution. I find assertions to be cheap and effective means of capturing programmer errors and would like assertions to be invoked during Release mode too.

Solution

assert is a macro and its existence during compilation is controlled by the definition of the NDEBUG identifier. If NDEBUG is defined, assertions are disabled. As you can guess, by default, NDEBUG is defined in Release mode.

So, to enable assertions in Release mode, go to the project properties → C/C++ → Preprocessor → Preprocessor Definitions and remove NDEBUG.

Tried with: Visual C++ 2008

CGAL: GMP and MPFR Linker Errors

Problem

Compiling any Visual C++ solution that uses CGAL produces either or both of these errors:

1>LINK : fatal error LNK1104: cannot open file 'gmp-vc90-mt.lib'
1>LINK : fatal error LNK1104: cannot open file 'mpfr-vc90-mt.lib'

Solution

CGAL seems to look for GMP and MPFR libraries, whose names are suffixed with the Visual C++ version (vc90) and the build type (mt). However, CGAL stopped shipping pre-built GMP and MPFR libraries in such a format a while ago. Instead it ships a single library file for each. For example, in CGAL 3.8, these files are libgmp-10.lib and libmpfr-4.lib.

With this knowledge, this error can be fixed and the solution can be compiled like this:

  1. Ignore the library dependencies that are indicated by CGAL. This can be done by going to Properties → Linker → Input → Ignore Specific Library and adding gmp-vc90-mt.lib,mpfr-vc90-mt.lib
  2. Link with the available libraries instead. This can be done by going to Properties → Linker → Input → Additional Dependencies and adding libgmp-10.lib libmpfr-4.lib

The Visual C++ solution using CGAL should be able to build and execute without errors now.

Tried with: Visual C++ 2008 and CGAL 3.8

CUDA: LNK2005 Linker Errors

The Problem

When building a Visual Studio solution which has CUDA source files (*.cu), LNK2005 linker errors of the following kind might be seen:

LIBCMT.lib(hooks.obj) : error LNK2005: "void __cdecl terminate(void)" (?terminate@@YAXXZ) already defined in MSVCRT.lib(MSVCR90.dll)

What does it mean?

This indicates a mismatch between the kind of C runtime library used by the CUDA Build Rule and that used for the rest of the Visual C++ project.

How to fix it?

This problem can be fixed by making both of these use the same kind of C runtime library. For example, if the Visual C++ project is compiled using Multi Threaded DLL (/MD) and the CUDA build rule has Multi Threaded (/MT), then change the CUDA build rule to use /MD too.

 

Tried with: CUDA 3.2 and Visual Studio 2008

Visual C++: Creating a New Configuration

Creating a new configuration for compilation in Visual C++ is easy!

For example, say I want to create a new configuration that is same as Release mode, except I want assert() to be compiled. To do this:

  • Choose Project → Properties and in the Properties dialog, choose Configuration Manager.
  • In the Active Solution Configuration dropdown, choose New.
  • In the New Solution Configuration dialog that pops up, give the new configuration a name (ReleaseWithAssert for example) and choose an existing configuration whose settings to copy from. For our example, I would choose to copy from Release. This creates a new configuration named ReleaseWithAssert with all the settings from the Release configuration.
  • Go into the new configuration settings and make the changes you want. For example, I typically enable assertions in Release mode by removing the definition of the NDEBUG preprocessor directive.

Visual C++: Windows and Console Subsystems

Subsystem

The Subsystem option can be found in any Visual C++ project here: Project → Properties → Linker → System → Subsystem. The choice of Subsystem decides the execution environment for the executable that is compiled from the project. For a Console application, choose /SUBSYSTEM:CONSOLE. For a Windows (GUI) application, choose /SUBSYSTEM:WINDOWS. There are other Subsystems, but these two are the most common.

Entry Point Function

The entry point function of the executable is decided based on the Subsystem. A Console executable begins from a main() function, so this should be present somewhere in the project code. A Windows executable begins from a WinMain() function, so this should be defined. If a windowing library (like wxWidgets for example) is being used, that library code would typically have the WinMain call defined inside.

Preprocessor Definitions

In older Visual C++ environments, the preprocessor definitions _CONSOLE and _WINDOWS corresponded to the above 2 subsystems. They are still defined by Visual C++ when it creates a project. These definitions are not really needed now. But, there might be header files of external libraries that you use, which might look out for these definitions. So, it might be a good idea to not delete them if you face errors.

Switching Subsystems

To switch a Visual C++ project from Console to Windows or vice versa, both the Subsystem and the Preprocessor Definitions need to be changed.

Errors

A project has a mismatched Subsystem when its code is written for Console and its Subsystem is set to Windows or vice versa. This manifests itself in errors like:

MSVCRTD.lib(crtexew.obj) : error LNK2019: unresolved external symbol _WinMain@16 referenced in function ___tmainCRTStartup

To fix this, make sure the Subsystem matches the code, else switch it.

Visual C++: CRT Source Code

The source code of the C Run-Time library (CRT) of Visual C++ can be found in the directory: C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\crt\src

Exploring the code, one sees that most of the C functions end up calling the Win32 API. The C++ library is licensed from Dinkumware. So, one can see the name of P. J. Plauger who created these files at their bottom. There are a few assembly files too (*.asm), which are mostly for memory and string operations.

Visual C++: C Run-Time Libraries

Every Visual C++ project is linked with a C run-time library. This is called the CRT in Microsoft literature.

Depending on the support for multi-threading there are 2 kinds of CRT:

  • Single threaded CRT: This can only be statically linked. This CRT is used if one of the compiler options /ML or /MLd is specified. It would be linked with libc.lib or libcd.lib respectively for Release and Debug modes. The single-threaded CRT is completely deprecated and should not be used! :x
  • Multi-threaded CRT: This is the default kind of CRT and should be used always.

The type of linking (static or dynamic) and the configuration (Release or Debug), lead to 4 kinds of multi-threaded CRT:

  • Release mode and statically linked: Specified using the compiler option /MT. The library file used is libcmt.lib.
  • Debug mode and statically linked: Specified using the compiler option /MTd. The library file used is libcmtd.lib.
  • Release mode and dynamically linked: Specified using the compiler option /MD. The library file used is msvcrt.lib and the DLL file used at run-time is msvcr100.dll (depends on Visual C++ version).
  • Debug mode and dynamically linked: Specified using the compiler option /MDd. The library file used is msvcrtd.lib and the DLL file used at run-time is msvcr100d.dll (depends on Visual C++ version).

Reference: C Run-Time Libraries at MSDN.

CPPUnit: Compiling with Visual C++ 2010

CPPUnit is a unit testing framework that is a port of the popular JUnit framework. Work on it has stalled and there has been no release since 2008. Work has continued on a fork called CPPUnit2.

The last released version of CPPUnit is 1.21.1. I needed it for a project, but compiling it with Visual C++ 2010 ended in lots of errors. I got it compiling after making some changes. This version can be downloaded from here.

The changes are:

  • The DSPlugIn project was removed.
  • The version was changed to 10.0 in the MSDevCallerListCtrl.cpp.
  • Changes made to the naming of .exe, .lib and .dll files produced by the projects in the CPPUnit solution.

Visual C++: Files and Directories

Visual C++ does not respect (or use) the underlying directory structure of your existing source code files. Some may find this to be a failing, but I personally think this is a feature. It allows you to organize your files in the way you want into one (or more) projects inside Solution Explorer.

Visual C++ Files

If a simple Visual C++ solution named Foobar is created with source files named Main.cpp and Main.h, it will have the following structure:

Foobar
|   Foobar.sln
|
+---Foobar
        Foobar.vcxproj
        Main.cpp
        Main.h

Foobar.sln is the Visual C++ solution file and Foobar.vcxproj is the Visual C++ project file. A solution can contain one or more projects. By default, when a solution is created, one project is created in the same name as that of the solution.

If another project named Foobar2 is added to the Foobar solution, the directory structure would look like this:

Foobar
|   Foobar.sln
|
+---Foobar
|       Foobar.vcxproj
|       Main.cpp
|
+---Foobar2
        Foobar2.vcxproj
        Main2.cpp

The solution file (Foobar.sln) and the project files (Foobar.vcxproj and Foobar2.vcxproj) are the only non-source files that are needed. Visual C++ might create a few more files and directories, all of them are not essential. So, if you plan to use a version control system (like Subversion or Mercurial) on this solution, you only need to backup .sln, .vcxproj, .cpp and .h files. For the comprehensive list of Visual C++ files that need to be checkedin to version control see this post.

Directory Structure

You can setup a convenient directory structure inside the directory that contains Main.cpp and Main.h. For example, creating a directory Foo with source files Foo.cpp and Foo.h:

Foobar
|   Foobar.sln
|
+---Foobar
    |   Foobar.vcxproj
    |   Main.cpp
    |   Main.h
    |
    +---Foo
            Foo.cpp
            Foo.h

No matter what is the directory structure, the source files can be imported into the Foobar Visual C++ solution and arranged in any fashion the user wants. The root directory of the Foobar project is Foobar/Foobar.

Including Directories

Header files at the root directory of the project can be directly included:

// Main.cpp
#include "Main.h"

For the header files lying inside directories of the project root directory, there are 2 ways to include them:

  1. Include the header file providing the relative path from the source file to the header:
    // Main.cpp
    #include "Main.h"
    #include "Foo/Foo.h"
    
  2. Open Project → Properties. Choose C/C++ → Additional Include Directories and add Foo. To add more include directories to the project, separate them with semicolons. The header files in the Foo directory can now be included without specifying any path in any .cpp or .h file in the project:
    // Main.cpp
    #include "Main.h"
    #include "Foo.h"
    

As you might deduce, strategy 1 gets messy pretty quickly since each file that includes another header needs to know the path that leads to it. For example, to include Main.h in Foo.cpp:

// Foo.cpp
#include "../Main.h"

Compared to this, using strategy 2 one can include any header file in any source file without worrying about the directory where it lies. This is much easier to apply across the directory structure of a project.