I have a C++ code which needs to include a certain library in some servers and not in other servers. I build my code using bjam.
Code example:
if server in server_list:
include <header-file.h>
int function();
else:
int function();
And during build using bjam:
if server in server_list:
-llibrary
else:
...
Header file inclusion is a compile time activity not run time. So you can't use if conditions for the same
use #ifdefs
#define SERVER_IN_LIST
#ifdef SERVER_IN_LIST
#include<...>
#endif
In C and C++ any line that begins with a # is a pre-processor directive. The pre-processor is a text parser that parses a source code file before it is compiled. It understands particular directives such as #include, #define and #ifdef but it treats normal C++ code as if it were text. For this reason, you can't use normal C++ code to alter the interpretation of the pre-processor directives.
Let's look at an example:
if (x == 4){
#include "x4.h"
}
The above is wrong because the if statement and its braces are part of the C++ code so will be ignored by the pre-processor. The pre-processor will go straight ahead and interpret the #include directive, which will cause the contents of x4.h to be pasted into that position in the file.
The correct way to write this is to use conditional pre-processor directives such as #if or #ifdef. For example...
#ifdef INCLUDE_X4
# include "x4.h"
#endif
Note that the indentation in this code is optional.
More information about pre-processor directives can be found here.
Related
I want to ask if I can make a file of macros that basically defined at compile time and use these macros in my c++ code which compiles specific code if the condition is true. SO what is basically the extension for that file is it a .txt file or a .h file. and how to put this file in CmakeList.txt to make it executable at compile time. for example like this in a specific file?
#define melodic 1
#define noetic 2
A C++ macro is a shortcut for writing code, what happens when you compile your project is that this code:
#define SOMETHING 32
int i = SOMETHING
Is changed to before it is compiled:
int i = 32
So a macro just substitutes text wherever you place it. There is also another use of macros that maybe is what you are looking for. You can use the preprocessing directive #ifdef MACRO to compile some code conditionally. For example, let's say that you have a function that is only there for debugging, but you don't want that code to make it to release. You could define it like:
void hello() {
#ifdef DEBUG
print("debug");
#endif
}
Then, if that file has a #define DEBUG before the #ifdef macro, the code will be included. Otherwise, the code will be discarded. Note that to use #ifdef the macro body may be empty or not, it just checks if the defined directive was used.
What you might want to accomplish is to have a series of preprocessor macros that you either set or don't in a separate configuration file to change the code produced. They are a very powerful tool, but they must be use with caution since having too many can make code not very readable.
To accomplish that, you need to include the #define MACRO in the same file that you are checking if it is defined, and before you check it. If you are only using that macro in that file, it would be good to place it at the top of it, but if you use it on multiple files you can create a header file (.h) and use #include "name.h", since include copies the contents of the header file there, therefore adding the macro definitions to your file.
The preprocessor directives are dependent on the compiler, so the version and type of compiler you use (gcc, clang...) will have different support for them. However, defined and ifdef are very widely spread and most if not all compilers have them. I recommend reading more about directives, for example here.
Finally, in case you go the route of the .h file, you would add it like any other header file you have in your project to the CmakeList.txt.
I have a single header C/C++ library which contains different inline functions whether the header is included from C or C++.
#ifndef __cplusplus
// C stuff
#else
// C++ stuff
#endif
The problem is that doxygen always parses just one of the two paths depending on whether I predefine __cplusplus myself or not. Entirely disabling preprocessing is no option either as I have other macros I'd like to keep in the documentation.
Is there any sane way to generate documentation for the C and the C++ part of the header?
I have a program that references an "nvml.h" file in order to execute some portion of the code. On my Linux machine, this is accomplished by including the following line in the header file:
#include "/usr/local/cuda/include/nvml.h"
However, I want the user to be able to run the program even if this file does not exist on their system. I have rendered the program modular so this can be accomplished, but I still need some method by which I can check if the file exists at all and, if not, abstain from including it in my header file.
I have tried an IF/DEF statement in order to get it working on both Windows and Linux:
#if defined(Q_OS_UNIX)
#include "usr/local/cuda/include/nvml.h"
#else
#include "C:/Users/thisUser/nvml.h"
But I cannot think of a method by which I can use the IF/DEF structure to check for file existence. Is there any way to do this with preprocessor directives in C++?
You should just do
#include "nvml.h"
set the include path while compiling depending on platform:
g++ -I/usr/local/cuda/include ...
But I cannot think of a method by which I can use the IF/DEF structure to check for file existence. Is there any way to do this with preprocessor directives in C++?
Since C++17, there is the macro __has_include which does exactly this.
Prior to C++17, there was no such directive in the standard, although may have been supported as an extension. A compiler may support command line argument to provide macro definitions, which can be utilised to forward the result of a check for existence prior to compilation.
That said, for your particular case, it might be better to simply include <nvml.h> and add the parent directory to include path. See the manual of your compiler for details - or use a build system to take care of it.
C++17 simplifies this a bit with __has_include which provides the ability to conditionally #include a file only if the file is found in the system.
#if __has_include( <optional> )
# include <optional>
#elif __has_include( <experimental/optional> )
# include <experimental/optional>
#else
//
#endif
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.
Is it possible to detect (and print out) programmatically where a C++ header got included from?
I have a header like:
// DeprecatedHeader.h
__pragma( message ("DeprecatedHeader.h is deprecated - include NewHeader.h instead.") )
#include "NewHeader.h"
As you can see, compiler is MSVC, but I have macros to wrap. GCC is welcome, but if not possible, I would enable the 'trick' just on Windows.
But what I'm looking for is an output like
"AnyOtherFile.cpp was including DeprecatedHeader.h, please include NewHeader.h instead."
Edit: To be clear why I want this: The warning the compiler throws is helping already a lot: the code is not broken but pokes the people to change the include. Problem: it may blame the wrong 'guy' as you could pull in this header via another header. My objective was to blame the erroneous header, not the compilation unit.
You can run your compiler with the option to produce the preprocessed source code rather than the fully compiled (gcc -E, CL.EXE /E or whatever) . The resulting code will include tagging of where each snippet of code comes from.
Even though I don't think it's worth pursuing this functionality, but here's a solution.
On top of each header file, after checking for deprecated header and before including other files, put this:
#undef INCLUDING_FILE
#define INCLUDING_FILE "file_name.h"
This can be done with a simple bash script where for each .h file you write this, including the file name in the string.
So your headers would look like this (with gcc):
Normal header:
#undef INCLUDING_FILE
#define INCLUDING_FILE "normal.h"
#include "deprecated.h"
Deprecated header:
#ifdef INCLUDING_FILE
# pragma message "Internal bug: " INCLUDING_FILE " included " __FILE__ " which is deprecated"
#else
# pragma message "Note: you shouldn't included " __FILE__ " which is deprecated"
#endif
#undef INCLUDING_FILE
#define INCLUDING_FILE "normal.h"
#include "others.h"
Not sure about an exact solution (probably it is possible to do with __FILE__ and other similar macros), but you could try #warning preprocessor directive placed into a wrong header file. During compilation it will issue a warning, which will notify about whatever you want.