Home > Uncategorized > Removing old-style inclusion guards from Visual C++ header files

Removing old-style inclusion guards from Visual C++ header files

Recent versions of Microsoft Visual C++ compiler support the following directive in C++ header files (.h):

#pragma once

This is used to prevent their multiple inclusion (prevents multiple definition of symbols and also spurious inclusion loops that could freeze the parser).

Before introduction of this directive (the #pragma command allows compilers to introduce compiler-specific features) one would use an inclusion guard of the following pattern in their C++ header files:

#if !defined(unique-guard-id)
  #define unique-guard-id
 
//normal header file code goes here
#endif

For the unique guard sometimes the .h filename was used in a form like "TEST_H" for a "test.h" C++ header file, or a combination of a GUID (a statistically unique number defined at Microsoft COM, based on OSF DCE’s UUID) and the filename, like "TEST_H_02A4AB75-4421-4dcf-952C-9819A27169C7"

Using "#pragma once" results in less noise to anyone reading that source code to understand it and work with it, since the less boilerplate stuff is at the top of a file, the less users have to scroll down to get to the real source code in it.

Moreover the header files are faster to parse that way (especially if a solution has a big number of C++ header files). It should be also noted that the VC++ compiler keeps a structure regarding header files that are marked using #pragma once, so the parser doesn’t bother to open them again if they’re included more than once. That isn’t the case obviously with the low efficiency old-style inclusion guards, which result in the parser opening the header file multiple-times and parsing it from start to end just to skip all of its inner content all times apart the first time it is parsed.

You might also see the following even more verbose and overkill pattern at some C++ header files:

#if !defined(guard)
  #define guard

  #if _MSC_VER > 1000
      #pragma once
  #endif

 
//normal header file code goes here
#endif

which could be as a first step automatically reduced to:

#if !defined(guard)
  #define guard

  #pragma once
 
//normal header file code goes here
#endif

To convert such constructs to a single #pragma once row the versatile "Replace in Files" action of Visual Studio IDE comes to the rescue, using the settings shown at the side-image. Note the \# and \n to escape the special # char and to define line change respectively and the * symbol (wildcard) that means "any text on the same line".

  VS2008_Project_RemoveInclusionGuardDefineKeepPragmaOnce

After the replace operation though you have to remove manually the #endif symbols at the end of the .h files where the replace operation was performed (that’s why I left the "Keep modified files open after Replace All" option checked). Just visit each file tab (pressing CTRL+TAB once quickly), then press CTRL+End to go to the file’s last line and then CTRL+L to delete that line (the #endif that is). No need to press CTRL+S to save the file or CTRL+F4 to close it, can work on all the open files and then use "Save All" and "Close All" menu actions.

Could also use the more powerful "Regular Expressions" mode to also remove the #endif automatically, but one would have to use find groups and match the whole inner text of the header file at the find string to then use it at the replace string and I’m not sure how big strings it can handle (probably it can handle it fine but don’t want to risk truncating your header files after a certain length, do you?).

Else, if the "Look in" field had an option to look in all open files and Microsoft supported a regular expression symbol for the virtual EOF (End-Of-File) mark, then one could do a 2nd pass instead to replace those #endif symbols at the end of only the open files (assuming you had closed all other files before doing the 1st pass, then all open files after the 1st pass would be the ones were a replacement has been done during that pass).

Advertisements
Categories: Uncategorized Tags:
  1. No comments yet.
  1. No trackbacks yet.

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 )

Twitter picture

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

Facebook photo

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

Google+ photo

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

Connecting to %s

%d bloggers like this: