CodeSOD: Include This
C and C++ are weird, specifically in the way they handle the difference between declarations and definitions. We frequently put our declarations in a header (.h) file, and the definitions associated with them in an implementation file- say, .cpp.
But things can only get declared once, which means if multiple implementation files depend on the same header, the compiler will yell at us. We need a way to ensure that, no matter how many times a header is referenced, it's only actually read once.
For some compilers, you can use #pragma once to tell the compiler to only include this file once. But that's compiler specific, so more traditionally, the formula is something more like this:
//myheader.h#ifndef MYHEADER_H_#define MYHEADER_H_//actual code declarations here#endif
We check if a precompiler definition has been given, and if it hasn't, we define it, then declare all of our code. This ensures that the actual declarations only happen once.
Which brings us to Nancy's nightmare. She had been changing some header declarations in a stringtools.h header, and try as she might, she couldn't get those changes to actually apply anywhere. In fact, it seemed like the header wasn't getting included ever.
Eventually, she saw this, buried in stringtools.cpp:
#define STRINGTOOLS_H_namespace StringTools{ std::string ToString(char * value) { if (value != 0) { return std::string(value); } else { return std::string(); } } ...}#include "stringtools.h"#include "otherheader.h"
Defining the include guard inside of the .cpp is, as Nancy put it "pure, undiluted evil." It's not a footgun, but a landmine, waiting for some intrepid developer to tread upon it. It's not a question of if it will cause someone a headache, but when.
[Advertisement] ProGet's got you covered with security and access controls on your NuGet feeds. Learn more.