I'm looking for a way to enforce that certain headers cannot be included into the same file.
To explain the situation further, assume I have the headers
a_1.h, b_1.h
and
a_2.h, b_2.h
I want to prevent the inclusion of _1 and _2 files into the same file, regardless of if they were
a_ or b_
Assuming that mixing the _1 and _2 headers is a mistake that needs to be caught, a simple way of catching it is to define and check guard macros to check for mixed usage of these headers and use the #error directive to report errors.
For example, the a_1.h header can include this code:
#ifndef A_1_H__INCLUDED
#define A_1_H__INCLUDED
/* Define header set as 1 if not already defined. */
#ifndef HEADER_SET
#define HEADER_SET 1
#endif
/* Check for consistent header set usage. */
#if HEADER_SET != 1
#error "Inconsistent header sets"
#endif
/* Other header stuff ... */
#endif /* A_1_H__INCLUDED */
The other headers will be similar but the _2 headers will have #define HEADER_SET 2 and #if HEADER_SET != 2.
Remember that ANY other file in the build process can include a header. With the typical include guard: #ifndef MYHEADER \n #include MYHEADER, the header code is only inserted on the first instance. After that, the compiler has eaten it and remembers and doesn't need to include it again. Think of compiling as putting ALL the source code into one file and turning that into a binary. (you know, "compiling" as in putting it all in a pile). So it's not "into the same file" it's "into the same build".
You want a header file to be mutually exclusive with another header file. (Like, say, if you've got code that targets specific hardware via includes, and you obviously can't build towards two chips at the same time.) First off, if that's an issue, you should really have a single place where such things are defined (like the build script) so that's not a problem. But if you want a simple safeguard:
#ifndef PPC_e6500
#define PPC_e6500
#ifdef LINUX
#error This processor ain't big enough for the both of us, Tux. This here's 8548 territory!
#endif
That will fail to build and you can figure out who did whatever horrible thing that tried to build towards two targets at once.
Related
I'm using Keil to code for STM32 microcontrollers. In main.h file, I use this code:
#if defined __has_include //Keil recognizes this preprocessor. If it was unavailable, Keil would have marked it as gray
#if __has_include("Debugg.h")
#include "Debugg.h"
#endif
#endif
This, checks if the Debugg.h file exists. Let's imagine I have a #define in Debugg.h file:
#define DEBUGGING 1
Now, I expect that in main.h, the DEBUGGING is defined. Again main.h:
#if defined __has_include //Keil recognizes this preprocessor. If it was unavailable, Keil would have marked it as gray
#if __has_include("Debugg.h")
#include "Debugg.h"
#endif
#endif
#ifdef DEBUGGING
#define MAIN_DEBUG 1 //This line runs
#else
#define MAIN_DEBUG 0 //Keil IDE mark this line as gray, meaning "unavailable code"
#endif
But, whenever I try to print MAIN_DEBUG or use it, it is 0!
NOTE:
It seems that Keil IDE recognizes the __has_include preprocessor, but the compiler DOES NOT; because when I comment out these lines:
//#if defined __has_include
#if __has_include("Debugg.h")
#include "Debugg.h"
#endif
//#endif
I get these errors:
compiling main.c...
..\Library\main.h(5): error: #59: function call is not allowed in a constant expression
#if __has_include("Debugg.h")
..\Library\main.h(5): error: #31: expression must have integral type
#if __has_include("Debugg.h")
..\Library\main.c: 0 warnings, 2 errors
I also use the default ARM compiler version 5. Any suggestions?
Thanks.
Any suggestions?
Do not use non-portable extensions like __has_include. Build systems are used to detect information about environment, like available headers.
For example, CMake build system has check_include_file that you can check if an include file exists. Then if the include file Debugg.h (why upper+lower case mix?) exists, then add a macro HAS_DEBUGG_H to compilation and if that macro is defined, then include the header.
a libX.c, a libX.h and libX_conf.h file. the checking for Debugg.h is in config file. If it was available, it checks for the prints of a specific thread. If not, debugging is deactivated
That should be done with a macro, not with "detecting header file". There should be a macro, called like LIBX_DEBUG_ENABLE and if defined, libX should output debugging information. I.e. it is a user configuration setting done with a macro, not with deleting a file.
I am doing a porting project implemented from INTEGRITY OS to UBUNTU. Facing compiler error as explained below. Even though not compiled in INTEGRITY OS, i think there is no errors there.
I got the root cause. I am expecting solution how i can achieve this.
main.c
#include "file1.h"
#include "file2.h"
#include "file3.h"
.
.
.
Inside all the files from
file1.h to file3.h below is there at the beginning of each file.
#ifdef INC_HEADER_FILE
#error Multiple header files included.
#endif
#define INC_HEADER_FILE
.
.
.
Above throws error while compiling
In file included from ../main.c:
../file1.h: error: #error Multiple application header files included.
# error Multiple application header files included.
^~~~~
Same error is thrown for all the files for file1.h to file3.h
If all three (or however many there are) of those header files use the same symbol INC_HEADER_FILE, then you will only be allowed to include one of them.
That's because including (for example) file1.h will set that symbol, meaning that including the next header will complain because it's already defined.
The include guard symbol is usually specific to the header file itself, such as INC_HEADER_1_FILE but it's my no means necessary - I've seen this sort of thing done when you only want one variation of a header file.
An example of that is a system I worked on for LED display devices where each header had different dimensions. These were constructed from 8x8 units but different quantities across and down. Having the LED addressing map in a header file allowed for efficiencies that weren't available with dynamic configuration and the include guard made sure we didn't try to use more than one map.
regarding the include guard for header1.h suggest:
#ifndef HEADER1_H
#define HEADER1_H
...
#endif
regarding the include guard for header2.h suggest:
#ifndef HEADER2_H
#define HEADER2_H
....
#endif
and similar for each header file.
The result is in any one compilation unit (source file.c) any specific header file can only be included once.
I'm fairly new to programming in C. My problem is that I have two implementations of a function and I want to be able to switch between them easily.
Right now I define the two implementations of the function as function_implementation1 and function_implementation1 in the files "funtion_implementation1.h" and "funtion_implementation2.h" respectively. To switch between them I have the following file:
#define IMPLEMENTATION1
#ifdef IMPLEMENTATION_1
#include "funtion_implementation1.h"
#define myFunction function_implementation1
#endif
#ifdef IMPLEMENTATION_2
#include "funtion_implementation2.h"
#define myFunction function_implementation2
#endif
In order to switch from one implementation to the other I just have to change the first line. This approach works, and I was satisfied with it for a while, but now it is bugging me that I have to open this file so often. I have a parameters.h file where I define all my parameters and I would rather choose which implementation to use in that file. Sadly, moving the first line to that file does not work. If I do that myFunction is not defined.
What is the best way to do this?
you should include your parameters file where you use alias, macros, etc:
#include "Parameters.h"
also, all your headers files should start with:
#ifndef __FILE_H__
#define __FILE_H__
// definitions go there
#endif
This prevents nested include of header files
Use preprocessor options, specifically the -D option. If you wanted to use IMPLEMENTATION1, when you are compiling that file on the command line (or in IDE), add -D IMPLEMENTATION1. This defines that macro. Same works for any macro
I am working on the source code of a Unix-based kernel. I noticed that the last line of each source code file (.c or .h) is a specific line with the following format:
__SRCVERSION( "$URL: ... $ $Rev: 219996 $" )
The URL points to the web address of the same file. I'm wondering what does that mean, and what is it actually for? Would it be any problem if I delete this line from all of my source code files?
Macros like this are often used to embed versioning information into binaries when they are compiled. They can be updated automatically when fetched out of a source control system with appropriate rules. Removing them shouldn't cause any harm, but you will lose the benefit of being able to search a binary to identify which versions of your source files were used to compile it.
As #Keith Thompson says below, it may also be possible to configure your build to not embed the information. Below is an example of the macro definition taken from here (different systems are likely to have different definitions). You can see that it uses the __USESRCVERSION definition to decide which version of the __SRCVERSION macro is used:
#ifndef __USESRCVERSION
#define __SRCVERSION(id)
#else /* __USESRCVERSION */
#ifdef __QNXNTO__
#if defined __SRCVERSION
#undef __SRCVERSION
#endif /*__SRCVERSION */
#define __SRCVERSION(id) \
__asm__(".section .ident,\"SM\",#progbits,1"); \
__asm__(".asciz " #id); \
__asm__(".previous");
#endif /* __QNXNTO__ */
#endif /* __USESRCVERSION */
I'm writing code that depends on whether or not a header file is included. If the file is included, I want certain added functionality. Is there any way to do this, perhaps with an #if? Using C btw
Just #define a symbol in that header and use #ifdef later on.
header.h
#define HAVE_IPV6
some_file.c
#ifdef HAVE_IPV6
/* code */
#endif
A technique commonly used with C headers is called include guards. The primary purpose is to prevent multiple-inclusion of header files, but they can also be used to address your need.
Include guards involve testing and conditionally setting a preprocessor constant within each header in your project, that is unique to a particular header file. To achieve this each header gets wrapped within an #ifndef/#endif block.
Example:
MyHeader1.h
#ifndef MY_HEADER_1_H
#define MY_HEADER_1_H
// header file contents...
#endif // MY_HEADER_1_H
MyHeader2.h
#ifndef MY_HEADER_2_H
#define MY_HEADER_2_H
// header file contents...
#endif // MY_HEADER_2_H
In your case, you can now test elsewhere in your code for the inclusion of any particular header file, e.g. #ifdef MY_HEADER_1_H