Short description:
Header.h has #include <stdbool.h> which has a Macro for _Bool in c.
file.cpp includes Header.h, but since file.cpp is C++ - it has bool as a native type. Now lint complains about a set of things due this (redeclaration, non-existing methods etc.). Is there a way to prevent inclusion of <stdbool.h> in file.cpp without touching Header.h?
If my description of a problem looks ridiculous - please throw tomatoes at me :) Otherwise, thanks for help.
Edit: Now thinking of this again: knowing the basic concepts of compilation and linking I should have realized that 'excluding' some header in downstream file/header sounds funny and should not be possible without cludges. But still, thanks for help. Another small brick to my understanding of this.
You could create your own stdbool.h and put it earlier in the include path so it is found before the system one. That's technically undefined behaviour, but you have a broken <stdbool.h> so it's one way to work around that. Your own version could either be empty (if it will only be included by C++ files) or if you can't prevent it also being used by C files then you could do:
#if __cplusplus
# define __bool_true_false_are_defined 1
#elif defined(__GNUC__)
// include the real stdbool.h using the GNU #include_next extension
# include_next <stdbool.h>
#else
// define the C macros ourselves
# define __bool_true_false_are_defined 1
# define bool _Bool
# define true 1
# define false 0
#endif
A cleaner solution would be to do this in file.cpp before including Header.h:
#include <stdbool.h>
// Undo the effects of the broken <stdbool.h> that is not C++ compatible
#undef true
#undef false
#undef bool
#include "Header.h"
Now when Header.h includes <stdbool.h> it will have no effect because it's already been included. This way is technically invalid (see comment below), but in practice will almost certainly work portably.
It needs to be done in every file that includes Header.h, so you could wrap it up in a new header and use that instead of Header.h e.g. CleanHeader.h that contains:
#ifndef CLEAN_HEADER_H
#define CLEAN_HEADER_H
// use this instead of Header.h to work around a broken <stdbool.h>
# include <stdbool.h>
# ifdef __cplusplus
// Undo the effects of the broken <stdbool.h> that is not C++ compatible
# undef true
# undef false
# undef bool
#e ndif
# include "Header.h"
#endif
Related
Please excuse my basic question and poor programming knowledge.
I have an implementation that I need to use in many of my projects. But the included header files are different for different projects.
Say I have spi.h header file to be used in projecta.c and projectb.c. But a particular include (definitions.h) is not required in projectb.c then how do I make this include project specific?
I have seen that is done through #ifdef and #ifndef and directives. But can someone please help me understand how is it done.
Thank you
Say I have spi.h header file to be used in projecta.c and projectb.c. But a particular include (definitions.h) is not required in projectb.c then how do I make this include project specific?
Like this:
// projecta.c
#include "spi.h"
#include "definitions.h"
// projectb.c
#include "spi.h"
There's no need for ifdef directive.
You can include a certain header depending on an #ifdef like that:
#ifdef INCL_DEFINITIONS
# include "definitions.h"
#endif
The in the project where you need definitions.h you have to add -DINCL_DEFINITONS to the compiler parameters
I have seen that is done through #ifdef and #ifndef and directives.
It can be done through #ifdef and #ifndef directives or #if directives.
The key part of this is you need some way to define preprocessor macros based on what project is being built. A common way this is done is:
Each project has its own build settings.
Those build settings include options to pass to the compiler.
The compiler has options to define preprocessor symbols.
For example, with GCC and Clang, you can use -Dsymbol to cause symbol to be defined (with no replacement tokens; it is defined, but the definition is empty) or -Dsymbol=replacement to cause it to be defined with the indicated replacement.
Once you have this, there are choices about how to use it. One choice is for a symbol to be defined if a feature should be included and undefined if not. Then you would have directives such as:
#if defined FeatureX
#include "HeaderForFeatureX.h"
#endif
Another choice is for a symbol to be defined to be 1 if the feature should be included and 0 if not. Then you would have:
#if FeatureX
#include "HeaderForFeatureX.h"
#endif
Historically, some people used the first choice and some people used the second. Because of this, it is common to write your settings and code to cover both of them. When defining a symbol with a compiler option, we will both define it (satisfying the first method) and define it to be 1 (satisfying the second method), as with -DFeatureX=1. When testing it, we will test with with #if defined FeatureX because that is true if either choice is used, whereas #if FeatureX is true only if FeatureX is defined to be 1, not just defined with empty replacement tokens.
(In a #if directive, if a token that could be a preprocessor macro name is not a defined preprocessor macro name, it is replaced with 0. So, if FeatureX is not defined, #if FeatureX becomes #if 0.)
A third choice is to define a symbol to have different values according to the features chosen. For example, we could define ProductLevel to be 10, 20, or 30, and then use directives such as:
#if 10 <= ProductLevel
#include "Level10Features.h"
#if 20 <= ProductLevel
#include "Level20Features.h"
#if 30 <= ProductLevel
#include "Level30Features.h"
#endif
#endif
#endif
Say I've two header files A.hpp and B.hpp and A.hpp gets included in the second file via #include "A.hpp" statement. Now when distributing the header files, I want another option which includes a single header file A_B.hpp which contains exactly the same code as the contents of A.hpp pasted over its #include statement.
For now I'm manually copy pasting the contents since releases are fewer and the size of files isn't much, but is there an automated way of doing something like this? Something like command B.hpp > A_B.hpp
Another thing to keep in mind, I don't want other preprocessor things like macro expansions, OS detection specific macros like -
#if defined(__unix__) || defined(__unix) || defined(__linux__)
#define OS_LINUX
#elif defined(WIN32) || defined(_WIN32) || defined(_WIN64)
#define OS_WIN
#elif defined(__APPLE__) || defined(__MACH__)
#define OS_MAC
#else
#error Unknown Platform
#endif
to get evaluated since they need to be present in the final file. Any other way to do such taks is also welcomed.
You'll need to write your own script for this. What you're asking for is far less than what gcc -E does (preprocess everything). Further, it's less than what cpp -fdirectives-only does, because you don't want to recurse. You effectively have a project-specific requirement, and you'll need to write project-specific code for it.
Perhaps you are looking for the unifdef utility.
Say I've two header files A.hpp and B.hpp and A.hpp gets included in the second file via #include "A.hpp" statement. Now when distributing the header files, I want another option which includes a single header file A_B.hpp which contains exactly the same code as the contents of A.hpp pasted over its #include statement.
Actually, you don't say what A.hpp & B.hpp are containing (and details are important). They probably are including some system headers (like <stdio.h> from C standard library, or <new> or <vector> headers from the C++ standard library).
Then, distributing their preprocessed form (the output of g++ -C -E b.hpp ...) is practically useless, because that form then contains some system and compiler specific declarations/definitions, which is not portable to another compiler (in practice the <map> from GCC 5 is probably not compatible with the <map> from GCC 6).
The whole point of standard libraries is that they are normalizing the name of headers (and their public interfaces) like <vector> or <stdio.h> but not the details of their contents (and private implementations). And compilation options (like -pthread or -std=gnu++11 or -O ...) may influence on the preprocessed form (notably thru common predefined macros).
You might use the -H preprocessor option to g++ to find out what is included (or even play tricks with various -M... options).
Perhaps you might want to distribute an amalgamation of your source code (like SQLite does), but that requires some careful design effort.
You could consider using some external preprocessor like m4 or GPP.
(but it is project-specific, and much less easy than what you think, precisely because of the role of standard headers in your project ones)
I know C or C++ code usually needs to use include guards like this:
#ifndef __A__H__
#define __A__H__
class A{
};
#endif
and to speed up compile time, in other cpp (e.g.:B.cpp), it can change
#include "A.h"
to:
#ifndef __A__H__
#include "A.h"
#endif
but the question is why doesn't the compiler automatically add or generate the include guard, and therefore why does the programmer need to add it manually if an include guard is usually required?
There are times when it is absolutely incorrect to generate the header guard. The standards contain an example: <assert.h> in C and <cassert> in C++.
The effect of reincluding those headers depends on the state of the NDEBUG macro when the header is (re)included. It is legitimate to write:
#undef NDEBUG
#include <assert.h>
…code using assert…
#define NDEBUG 1
#include <assert.h>
…more code using assert…
If the compiler automatically generated a header guard, that would not work correctly. Therefore, compilers do not generate header guards automatically.
Incidentally, user code should not use header guard macro names that start with double underscore, or underscore capital letter. Such names are reserved for the implementation. In C++, no user-defined name may legitimately contain a double underscore at all. Use something more like:
#ifndef A_H_INCLUDED
#define A_H_INCLUDED
…body of header…
#endif
The compiler, or more strictly the pre-processor cannot determine the programmer's intent in using inclusion. The compiler does not explicitly distinguish between .h files and .c or .cpp files; they differ only in the type of code one places in them. In fact the compiler deals only in a single translation unit; it is the responsibility of the C preprocessor to concatenate all included files into a single file for compilation. It would be incorrect for the pre-processor to omit an inclusion that it has previously included because it has no semantic knowledge of the code and may cause intended behaviour to change by second-guessing the developer.
In some circumstances, an IDE may add include guards for template code that it has generated. For example Microsoft Visual Studio will add them for code that it generates via its project start-up wizards. If it happens at all, it is properly the responsibility of the IDE rather than the compiler or pre-processor.
Motivation:
I want to enable the memory detection of VC++, which requires that some statements must be at the forefront as follows:
#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
Question:
Suppose I have a header file forefront.h, what I want is the following effect:
a.cpp
#include <any_other_one.h>
#include <forefront.h> // An compiler error generated here!
b.cpp
#include <forefront.h> // OK
#include <any_other_one.h>
How to implement?
Create your own header file with the following contents:
#define _CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>
Now use the Forced Includes setting in the Advanced section of the project's settings. Any file specified there will be included before all others, in the order specified.
Since what you're really asking is how to ensure _CRTDBG_MAP_ALLOC is defined in all compilation units, use the VC++ project system to add that definition. Go to the project properties dialog, and in the C++ Preprocessor section add _CRTDBG_MAP_ALLOC to the Preprocessor Definitions line.
I think this is the most non-intrusive solution I come up with,
put the following at the beginning of forefront.h,
#if (__LINE__ != 0)
#error ERROR_FORE_FRONT_IS_NOT_THE_FIRST_TO_INCLUDE
#endif
you don't need to change others.h.
I tested this code with GCC 4.6.3.
I guess something like this might work:
other.h
#ifndef OTHER_H_
#define OTHER_H_
...
#endif
forefront.h
#ifdef OTHER_H_
#error Wrong include order
#endif
Just seen this inside <boost/asio.hpp>
#ifndef BOOST_ASIO_HPP
#define BOOST_ASIO_HPP
#if defined(_MSC_VER) && (_MSC_VER >= 1200)
# pragma once
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
/// ....
#endif // BOOST_ASIO_HPP
Disregarding the _MSC_VER preprocessor checks, what is the benefit of having the #pragma once in this case? Doesn't the preprocessor header guard ensure in all cases and on all platforms, the header contents are only ever included once?
#pragma once specifies that the file will be included (opened) only once by the compiler when compiling a source code file. This can reduce build times as the compiler will not open and read the file after the first #include of the module.
If you don't #pragma once, the file will be opened each time it is needed and compiler will stop parsing it on #ifndef BOOST_ASIO_HPP, if it has been defined.
Specifies that the file will be included (opened) only once by the compiler in a build. This can reduce build times as the compiler will not open and read the file after the first #include of the module
And one more related question from SO
Yes header guards ensures that the header contents are included only once. but here you are using #pragma for checking another definition and not include file.
The below link is existing question on header guards in SO.
Purpose of Header guards
#pragma once has the same purpose, but include guards are intended to require a deeper analysis to ensure a file is included exactly once - e.g.
// somerandomfileinmyproject.cpp
#undef BOOST_ASIO_HPP
#include <bost/asio.cpp>
Unless the compiler does handle such cases correctly, it still needs to open the file and pass it through the preprocessor even though it has been included before.
You can reproduce the effect of the #pragma once in a standard way using the following:
#if !defined GUARD_SYMBOL
#include "GUARDED_FILE"
#endif
although it is much more verbose. As others have said, it helps with compilation times since the file is not searched for / opened instead of opening the file and ignoring everything inside it - the file still has to be parsed by the preprocessor.