How to avoid long compilation time for #define in common header - c++

I was wondering if there is an elegant way to solve this problem. Suppose there's a common header eg
// common.h
#ifndef COMMON_H
#define COMMON_H
#define ENABLE_SOMETHING
//#define ENABLE_SOMETHING_ELSE
#define ENABLE_WHATEVER
// many others
#endif
Now this file is included by, let's say 100 other header files and the various #define are used to enable or disable some parts of code which are confined to just 1-2 files.
Everytime a single #define is changed the whole project seems to be rebuilt (I'm working on Xcode 5.1), which makes sense as it must be literally replaced all around the code and the compiler can't know a priori where it's used.
I'm trying to find a better way to manage this, to avoid long compilation times, as these defines are indeed changed many times. Splitting each define in their corresponding file/files could be a solution but I'd like the practical way to have everything packed together.
So I was wondering if there is a pattern which is usually used to solve this problem, I was thinking about having
// common.h
class Enables
{
static const bool feature;
};
// common..cpp
bool Enables::feature = false;
Will this be semantically equivalent when compiling optimized binary? (eg. code inside false enables will totally disappear).

You have two distinct problems here:
Splitting each define in their corresponding file/files could be a solution but I'd like the practical way to have everything packed together.
This is your first problem. If I undestand correctly, if you have more than one functional area, you are not interested in having to include a header for each of them (but a single header for everything).
Apply these steps:
do split the code by functionality, into different headers; Each header should contain (at most) what was enabled by a single #define FEATURESET (and be completely agnostic to the existence of the FEATURESET macro).
ensure each header is only compiled once (add #pragma once at the beginning of each feature header file)
add a convenience header file that performs #if or #ifdef based on your defined features, and includes the feature files as required:
// parsers.h
// this shouldn't be here: #pragma once
#ifdef PARSEQUUX_SAFE
#include <QuuxSafe.h>
#elif defined PARSEQUUX_FAST
#include <QuuxFast.h>
#else
#include <QuuxSafe.h>
#endif
// eventually configure static/global class factory here
// see explanation below for mentions of class factory
Client code:
#include <parsers.h> // use default Quux parser
#define PARSEQUUX_SAFE
#include <parsers.h> // use safe (but slower) Quux parser
So I was wondering if there is a pattern which is usually used to solve this problem
This is your second problem.
The canonical way to enable functionality by feature in C++, is to define feature API, in terms of base classes, class factories and programming to a generic interface.
// common.h
#pragma once
#include <Quux.h> // base Quux class
struct QuuxFactory
{
enum QuuxType { Simple, Feathered };
static std::unique_ptr<Quux> CreateQuux(int arg);
static QuuxType type;
};
// common.cpp:
#include <common.h>
#include <SimpleQuux.h> // SimpleQuux: public Quux
#include <FeatheredQuux.h> // FeatheredQuux: public Quux
std::unique_ptr<Quux> QuuxFactory::CreateQuux(int arg)
{
switch(type) {
case Simple:
return std::unique_ptr<Quux>{new SimpleQuux{arg}};
case Feathered:
return std::unique_ptr<Quux>{new FeatheredQuux{arg}};
};
// TODO: handle errors
}
Client code:
// configure behavior:
QuuxFactory::type = QuuxFactory::FeatheredQuux;
// ...
auto quux = QuuxFactory::CreateQuux(10); // creates a FeatheredQuux in this case
This has the following advantages:
it is straightforward and uses no macros
it is reusable
it provides an adequate level of abstraction
it uses no macros (as in "at all")
the actual implementations of the hypothetical Quux functionality are only included in one file (as an implementation detail, compiled only once). You can include common.h wherever you want and it will not include SimpleQuux.h and FeatheredQuux.h at all.
As a generic guideline, you should write your code, such that it requires no macros to run. If you do, you will find that any macros you want to add over it, are trivial to add. If instead you rely on macros from the start to define your API, the code will be unusable (or close to unusable) without them.

There is a way to split defines but still use one central configuration header.
main_config.h (it must not have an include guard or #pragma once, because that would cause strange results if main_config.h is included more than once in one compilation unit):
#ifdef USES_SOMETHING
#include "something_config.h"
#endif
#ifdef USES_WHATEVER
#include "whatever_config.h"
#endif
something_config.h (must not have include guards for the same reason as main_config.h):
#define ENABLE_SOMETHING
All source and header files would #include only main_config.h, but before the include they must declare what part of it would they be referring to:
some_source.cpp:
#define USES_SOMETHING
#include "main_config.h"
some_other_file.h:
#define USES_WHATEVER
#include "main_config.h"

Related

How do I make header files?

I have gotten to a point in my course where they use Code::Blocks to automatically make a header file. However, I don't think it's necessary to download Code::Blocks specifically for this reason, and so I am looking for a way to make my own header files.
And so, I started my search online to find out exactly how to do this.
I checked How to create my own header file in c++? [closed] and also cplusplus.com
However, the former uses uses #ifndef YOUR_NAME_INCLUDE and #define YOUR_NAME_INCLUDE whereas the latter uses #ifndef __X_H_INCLUDED__ and #define __X_H_INCLUDED__, with 2 underscores surrounding the #ifndef and #define. How should I format my header guards? Does it really matter?
For example, if I have a file foo.h, which looks like this:
#ifndef ???
#define ???
int sum(int a, int b) {
return a + b;
}
#endif
should I put SUM_INCLUDED, FOO_INCLUDED, FOO_H instead of the ??? or something else altogether?
Second, is making a header file really as easy as just sticking a .h or .hpp to the end of it?
#ifndef FOO
#define FOO
struct foo {};
#endif
The above canonical example ensures that the contents (between #ifndef FOO and #define FOO) are compiled only once allowing us to include this file (say foo.h) in multiple compilation units without causing struct foo to be multiply defined.
There really isn't any "magic" about an include file other than this. In fact, the extension doesn't even matter. It could be foo.h or foo.hh or just foo (like the standard library headers like vector or iostream).
Ultimately, it's personal preference how you structure your include guards. Some use __FOO__ (note this runs afoul of C++ standard regarding reserved identifiers) or FOO_H_INCLUDED (which is standard compliant) while others may elect for different patterns.
While it's not strictly standard C++, my team uses #pragma once and foregoes the ifndef/define/endif code. It's supported by all the compilers we use (gcc/msvc/clang) and you don't have drawbacks such as too different foo.h files causing one (or the other) definition to be excluded.
The same file then looks like this
#pragma once
struct foo {};

Can/should I type whatever I want after #ifndef?

Example:
#ifndef HEADER_h
#define HEADER_h
#endif
Instead of HEADER_h, can I do the following?
#ifndef HEADER
or
#ifndef LIBRARY
or
#ifndef SOMETHING
or
#ifndef ANOTHERTHING
etc.
Header guards are just a convention, a "trick", making use of preprocessor conditions. In using a header guard you are creating a macro with a name, and checking whether that macro was already defined.
There is nothing magical about this macro that binds it to the filename of a header, and as such you can call it whatever you want (within reason).
That doesn't mean that you should write #ifndef URGLEBURGLE, though. You want the name to be useful and unique, otherwise there's not much point.
Typically something like #ifndef [PROJECTNAME]_[FILENAME]_INCLUDED is a good idea.
Yes, you can name the include guard symbol whatever you want, but bear in mind that they are supposed to be unique across headers. You definitely don't want a header
// first.h
#ifndef NON_UNIQUE_H
#define NON_UNIQUE_H
void foo();
#endif
and another one
// second.h
#ifndef NON_UNIQUE_H
#define NON_UNIQUE_H
void bar();
#endif
When you include both in one translation unit, one will "win" and its declarations will be visible, e.g.
// main.cpp
#include "first.h" // now, NON_UNIQUE_H is defined
#include "second.h" // NON_UNIQUE_H already there, doesn't do anything
int main(int, char**)
{
bar(); // error, won't compile, bar() isn't declared
}
Besides the necessity to circumvent such scenarios, it's best to stick to some convention throughout your project. One classical way of doing it is to convert the header file base name to upper case and append _H. If you have header files with the same base name in different directories, you can include the directory name, e.g. SUBDIR_FOO_H and OTHERSUBDIR_FOO_H. But this is up to you.
You can use a construction like
#if !defined(HEADER) || !defined(LIBRARY)
At your question, you are using
#ifndef HEADER_h
#define HEADER_h
#endif
It's the same as "#pragma once"
And yes, you can use different names of defines. In your case, LIBRARY, SOMETHING, HEADER_h - defines, that you can set in code(#define MY_VAR_NAME) or via compiler options(flag -DMY_VAR_NAME).
Your example is a so-called header guard that allows us to ensure the contents of the header are included only once. However, that is not the only use of #ifndef.You can use #ifndef for conditional compilation as in
#ifndef NO_DEBUG
do_some_debug_stuff();
#endif
So it is not only for header guards, but in general you have to carefully choose the name of the symbols you are introducing to prevent they are clashing with symbols defined elsewhere. It is just that header guards are so common that certain conventions exist (eg using FOLDER_FILENAME_H is usually sufficient to ensure uniqueness). And you need to be aware that certain names are reserved (eg starting with two underscores or underscore followed by capital letter).

Why do you need inclusion guard for C++ header files?

I get roughly what it does. What I don't understand is why it's not the default? What are the use cases where some header file would need to be included multiple times?
The reason it's not the default is primarily historical these days -- when the C language was formalized, #include was specified that it must act exactly as if the user had copy-and-pasted the specified file's contents at the location of the #include-line; and C++ wanted (and wants) to remain as compatible as possible with C, so C++ inherited that behavior from C.
As for a use-case where including the same header file more than once might be useful; one instance where I found it useful was for simulating a templated-container-class in C (because C doesn't support templates directly). I had a container-implementation-header-file that looked something like this (but more elaborate; I'm showing a simplified version here for readability):
// MyContainerImplemention.h
// be sure to #define MYTYPE and MYARRAYSIZE
// before #include-ing this file!
struct ArrayOf##MYTYPE
{
MYTYPE arrayOfItems[MYARRAYSIZE];
};
inline void Set##MYTYPE##Item(struct ArrayOf##MyType * container, int which, MYTYPE item)
{
container[which] = item;
}
[... and so on for various other MYTYPE-specific methods ...]
... then my .c files could do something like:
#define MYTYPE int
#define MYARRAYSIZE 10
#include "MyContainerImplementation.h"
#undef MYARRAYSIZE
#undef MYTYPE
#define MYTYPE short
#define MYARRAYSIZE 15
#include "MyContainerImplementation.h"
#undef MYARRAYSIZE
#undef MYTYPE
struct ArrayOfint myInts;
struct ArrayOfshort myShorts;
SetintItem(&myInts, 5, 12);
SetshortItem(&myShorts, 3, 2);
[...]
... and end up with the container "class" and its associated methods implemented for each data-type, without having to manually write a new implementation of the container "class" each time.
Yes, it was extremely ugly -- but not as ugly as having to manually write out thousands of lines of redundant container-code would have been. (The real container-implementation-header-file implemented a hash table and was several hundred lines long)
Without include guards or #pragma once the compiler would have to maintain a list of included files. This is not easy, because of different possible paths to these files (and #pragma once doesn't completely solve this) and would be expecting a bit much of the original C compilers, which had to work with very limited memory.
What's true today is not necessarily true when C came about and the C pre-processor, upon which the C++ one is based, was created.
#pragma once is just a step towards having proper C++ modules so this annoying historical legacy is finally eliminated.
Yes, it's valid to include a file multiple times, and yes, each time it's included it can behave in entirely different ways. This is why making pre-compiled headers is a huge headache for compiler developers.
Guard blocks or #pragma once are included in order to prevent a file from being included multiple times.
#pragma once, while supported on most compilers, is not an official part of the c++ standard, and may not work on every compiler. You can use a guard block, which will work on any compiler. An example of a guard block in the file MyClass.hpp would be:
#ifndef MYCLASS_HPP
#define MYCLASS_HPP
//Code here
#endif

Different definitions for the same classes in C++ - handling multiple targets

my problem is that i would like to organize my code so i can have a debug and release version of the same methods, and i can have multiple definitions of the same methods for different targeted platforms.
Basically the core of the problem is the same for both, i need to have the same signature but with different definitions associated.
What is the best way to organize my code on the filesystem and for compilation and production so i can keep this clean and separated ?
Thanks.
// #define DEBUG - we're making a non debug version
#ifdef DEBUG
// function definition for debug
#else
// function definition for release
#endif
The same can be done for different operating systems. There's of course the problem of recompilating all of it, which can be a pain in the ass in C++.
I suggest you to intervene at source level and not on header files (just to be sure to keep same interfaces), something like:
//Foo.h
class Foo{
void methodA();
void methodB();
};
//Foo.cpp
// common method
Foo::methodA() { }
#ifdef _DEBUG_
Foo::methodB() { }
#elif _PLATFORM_BAR_
Foo::methodB() { }
#else
Foo:methodB() { }
#endif
If, instead, you want to keep everything separated, you will have to work on a higher lever, the preprocessor is not enough to conditionally include a .cpp file instead that another. You will have to work with the makefile or whatever you use.
Another choice could be the one of having source files that simply disappear when not on specific platform, eg:
//Foo.h
class Foo{
void methodA();
void methodB();
};
//FooCommon.cpp
void Foo::methodA() { }
//FooDebug.cpp
#ifdef _DEBUG_H
void Foo::methodB() { }
#endif
//FooRelease.cpp
#ifndef _DEBUG_H_
void Foo::methodB() { }
#endif
If your compiler allows, you can try keeping the source files for each version in a separate subfolder (eg #include "x86_d/test.h") then using global macro definitions to control the flow:
#define MODE_DEBUG
#ifdef MODE_DEBUG
#include "x86dbg/test.h"
#else
#include "x86rel/test.h"
#endif
You can also use a similar structure for member function definitions, so that you can have two different definitions in the same file. Many compilers also use their own defines for global macros as well, so instead of #define MODE_DEBUG above, you might be able to use something like #ifdef _CPP_RELEASE or maybe even define one through a compiler flag.

Is there a way to instruct a C++ compiler to skip rest of current file?

Once in a while some functionality has to be conditionally compiled. For example, there's class Logger that is only used when WITH_LOGGING macro is #defined:
// Logger.cpp
#ifdef WITH_LOGGING
#include <Logger.h>
// several hundred lines
// of class Logger
// implementation
// follows
#endif
which is not very convenient - unless the reader scrolls through the file he can't be sure that the matching #endif is position at the end of file and so the whole file contents is excluded with the #ifdef. I'd prefre to have something like this:
// Logger.cpp
#ifndef WITH_LOGGING
#GetOutOfThisFile
#endif
#include <Logger.h>
// several hundred lines
// of class Logger
// implementation
// follows
so that it's clear that once the WITH_LOGGING is not #defined the compiler just skips the rest of the file.
Is something like that possible in C++?
An easy way to clarify this would be to put the implementation in another file which is included:
file Logger.cpp:
#ifdef WITH_LOGGING
#include <Logger.h>
#include "logger.impl"
#endif
file logger.impl:
// several hundred lines
// of class Logger
// implementation
// follows
Why are you trying to exclude the contents of that file? If I understand correctly, the code in it would not be used if the define was not set. In that case, link-time optimization should remove those functions from the executable regardless.
This won't work if you have functions overridden from other libraries, but for the regular case (and most likely for logging) this will be enough. In GCC this is --ffunction-sections for the compiler and --gc-sections for the linker. Visual Studio should have comparable flags but I don't know what they are.