What would the purpose of this construct in a c file be?:
#define _TIMERC
#include "timer.h"
#undef _TIMERC
I am aware of the guard for preventing multiple inclusion of a header file. This doesn't appear to be whats happening though.
thanks!
Here's a scenario to illustrate...
Lets say that timer.h provides a macro tick_count() that returns the number of timer interrupts that occured.
One module (rpm_reader.h) using timer A for interval timing:
#define _TIMERA
#include "timer.h"
#undef _TIMERA
In another module (lap_time.h) is using timer C for its interval timing
#define _TIMERC
#include "timer.h"
#undef _TIMERC
The rpm_reader would return the tick count from timer A when it called tick_count() and lap_time would get its count from timer C.
(My apologies for answering my own question, but asking the question helped me come to this revelation.)
Often times a library header file will have multiple options, that are enabled and disabled by macro defines. This will enable such an option.
More typically these are set at a global scope by configuring your build system to add (for eg with gcc) -D_TIMERC to the compilers command line.
I was wondering if it could be this:
The header file in this case is intended to allow multiple inclusions with different defines established before the each #include.
If in the timer.h there is a block of code (interrupt code) for timers A, B and C for each timer in the microcontroller. In some cases timer A is required in one module and timer C is required in another module.
I think your self-answer is right. There is most likely conditional stuff in the included header and the "calling" file knows which specific set of conditional "stuff" it wants to include.
It does not necessarily have to do with multiple includes - it can just be special cases depending on the "calling" context.
I am not exactly sure why one would undefine though. I can't think of a case where I would mix and match so not sure why an undefine is necessary.
At the risk of stating the obvious, "timer.h" expects to have _TIMERC and the rest of your code does not.
Clearly not good practice in the general case, but I have seen similar when including third party code. Can get nasty when you have #defs that clash...
For the record, common practice to avoid multiple includes of the same header file is to put the guard in the file itself, not to rely on some external define... ^_^
The headers start with:
#ifndef header_name_h
#define header_name_h
and end with:
#endif
Of course, the def style can vary.
Thus, on first inclusion, we go past the #ifndef (not yet defined) and we set the macro.
On second inclusion, if any, we just jump to end of file, nothing is included.
Related
What is the scope of a #define?
I have a question regarding the scope of a #define for C/C++ and am trying to bet understand the preprocessor.
Let's say I have a project containing multiple source and header files. Let's say I have a header file that has the following:
// header_file.h
#ifndef __HEADER_FILE
#define __HEADER_FILE
#define CONSTANT_1 1
#define CONSTANT_2 2
#endif
Let's then say I have two source files that are compiled in the following order:
// source1.c
#include header_file.h
void funct1(void)
{
int var = CONSTANT_1;
}
// source2.c
#include header_file.h
void funct2(void)
{
int var = CONSTANT_2;
}
Assuming I have included all the other necessary overhead, this code should compile fine. However, I'm curious as to what #defines are remembered between compilations. When I compile the above code, are the contents of each #include actually included, or are the include guards actually implemented?
TLDR: Do #defines carry over from one compilation unit to the next? Or do #define only exist within a single compilation unit?
As I type this out, I believe I'm answering my own question and I will state my believed answer. #defines are constrained to a single compilation unit (.c). The preprocessor essentially forgets any #defines when it goes from one compilation unit to the next. Thus in the above example I listed, the include guards do not come into play. Am I correct in this belief?
source1.c is compiled separately from source2.c therefore your defines are processed for source1 as it is compiled and then as an independent action they are processed for source2 as it is compiled.
Hopefully this is a clear explanation.
Preprocessor macros do not have "scope" as such, they just define a piece of text that should replace the macro in the code.
This means that the compiler never sees the strings CONSTANT_1 and CONSTANT_2 but instead gets the source in a preprocessed form with these macros replaced with their expansions (1 and 2 respectively).
You may inspect this preprocessed source by calling gcc with the -E flag, or with whatever flag only does preprocessing on your particular compiler.
Yes, you are right!!
Compilation of a file, in it self, is merely, just a process under execution. One process can not interfare with another unless explicitly done. The c pre-processors are just literal substitution mechanism, performed in a dumb way. Whatever conditional checking are performed, are confined to ongoing instance of pre-processor only, nothing gets carry forward once execution (compilation) comes to end. Pre-processors do not "configure" compiler, their scope is limited till "their own compilation"
I am using both the JUCE Library and a number of Boost headers in my code. Juce defines "T" as a macro (groan), and Boost often uses "T" in it's template definitions. The result is that if you somehow include the JUCE headers before the Boost headers the preprocessor expands the JUCE macro in the Boost code, and then the compiler gets hopelessly lost.
Keeping my includes in the right order isn't hard most of the time, but it can get tricky when you have a JUCE class that includes some other classes and somewhere up the chain one file includes Boost, and if any of the files before it needed a JUCE include you're in trouble.
My initial hope at fixing this was to
#undef T
before any includes for Boost. But the problem is, if I don't re-define it, then other code gets confused that "T" is not declared.
I then thought that maybe I could do some circular #define trickery like so:
// some includes up here
#define ___T___ T
#undef T
// include boost headers here
#define T ___T___
#undef ___T___
Ugly, but I thought it may work.
Sadly no. I get errors in places using "T" as a macro that
'___T___' was not declared in this scope.
Is there a way to make these two libraries work reliably together?
As greyfade pointed out, your ___T___ trick doesn't work because the preprocessor is a pretty simple creature. An alternative approach is to use pragma directives:
// juice includes here
#pragma push_macro("T")
#undef T
// include boost headers here
#pragma pop_macro("T")
That should work in MSVC++ and GCC has added support for pop_macro and push_macro for compatibility with it. Technically it is implementation-dependent though, but I don't think there's a standard way of temporarily suppressing the definition.
Can you wrap the offending library in another include and trap the #define T inside?
eg:
JUICE_wrapper.h:
#include "juice.h"
#undef T
main.cpp:
#include "JUICE_wrapper.h"
#include "boost.h"
rest of code....
I then thought that maybe I could do some circular #define trickery like so:
The C Preprocessor doesn't work this way. Preprocessor symbols aren't defined in the same sense that a symbol is given meaning when, e.g., you define a function.
It might help to think of the preprocessor as a text-replace engine. When a symbol is defined, it's treated as a straight-up text-replace until the end of the file or until it's undefined. Its value is not stored anywhere, and so, can't be copied. Therefore, the only way to restore the definition of T after you've #undefed it is to completely reproduce its value in a new #define later in your code.
The best you can do is to simply not use Boost or petition the developers of JUCE to not use T as a macro. (Or, worst case, fix it yourself by changing the name of the macro.)
I would like to know if it's possible that inside the main() function from C to include something.
For instance, in a Cell program i define the parameters for cache-api.h that later in the main() function i want to change .
I understood that what was defined with #define can be undefined with #undef anywhere in the program, but after redefining my needed parameters I have to include cache-api.h again . Is that possible?
How can I solve this problem more elegant ? Supposing I want to read from the main storage with cache_rd(...) but the types would differ during the execution of a SPU, how can i use both #define CACHED_TYPE struct x and #define CACHED_TYPE struct y in the same program?
Thanks in advance for the answer, i hope i am clear in expression.
#define and #include are just textual operations that take place during the 'preprocessing' phase of compilation, which is technically an optional phase. So you can mix and match them in all sorts of ways and as long as your preprocessor syntax is correct it will work.
However if you do redefine macros with #undef your code will be hard to follow because the same text could have different meanings in different places in the code.
For custom types typedef is much preferred where possible because you can still benefit from the type checking mechanism of the compiler and it is less error-prone because it is much less likely than #define macros to have unexpected side-effects on surrounding code.
Yes, that's fine (may not be the clearest design decision) but a #include is just like a copy-and-paste of that file into the code right where the #include is.
#define and #include are pre-processor macros: http://en.wikipedia.org/wiki/C_preprocessor
They are converted / inlined before compilation.
To answer your question ... no, you really wouldn't want do do that, at least for the sake of the next guy that has to try and unscramble that mess.
You can #include any file in any file. Whether it is then valid depends on the content of the file; specifically whether that content would be valid if it were entered directly as text.
Header files generally contain declarations and constructs that are normally only valid outside of a function definition (or outside any kind of encoding construct) - the clue is in the name header file. Otherwise you may change the scope of the declarations, or more likley render the compilation unit syntactically invalid.
An include file written specially for the purpose may be fine, but not just any arbitrary header file.
General purpose header files should have include guards to prevent multiple declaration, so unless you undefine the guard macro, re-including a header file will have no effect in any case.
One possible solution to your problem is to create separately compiled modules (compilation units) containing wrapper functions to the API you need to call. Each compilation unit can then include the API header file after defining the appropriate configuration macros. You will then have two separate and independent interfaces provided by these wrapper functions.
I'm learning C and hope someone can explain what's the logic of using #ifndef?
I also find many C programs I looked, people seems following a convention using the filename following the #ifndef, #define and #endif. Is there any rule or tip on how to choose this name?
#ifndef BITSTREAM_H
#define BITSTREAM_H
#include <stdio.h>
#include <stdint.h>
/*Some functions*/
#endif
Header files will often use logic like this to avoid being included
more than once. The first time a source file includes them, the name
isn't defined, so it gets defined and other things are done.
Subsequent times, the name is defined, so all that is skipped.
The one you posted, in particular, is called an Include Guard.
The term for what you're looking for is Preprocessor Directives.
#ifndef doesn't need to be followed by a filename, for example it's common to see #ifdef WINDOWS or #ifndef WINDOWS, etc.
#ifndef means "if not defined". It is commonly used to avoid multiple include's of a file.
Tom Zych: "Header files will often use logic like this to avoid being included more than once."
This is true but it really is only necessary for "public" headers, like headers for library functions, where you don't have any control over how the headers are included.
This trick is unnecessary for headers used in projects where you have control over how things are included. (If there's a use for them outside of public headers, it's not a common one).
If you avoid using them in "private" headers, you'll more likely include headers in a less haphazard way.
If I have a several header files :lets say 1.h, 2.h, 3.h.
Let's say the all three of the header files have #include <stdlib.h> and one of the include files in them.
When I have to use all 3 header files in a C file main.c,
it will have 3 copies of #include <stdlib.h> after the preprocessor.
How does the compiler handle this kind of conflict?
Is this an error or does this create any overhead?
If there are no header guards, what will happen?
Most C headers include are wrapped as follows:
#ifndef FOO_H
#define FOO_H
/* Header contents here */
#endif
The first time the preprocessor scans this, it will include the contents of the header because FOO_H is undefined; however, it also defines FOO_H preventing the header contents from being added a second time.
There is a small performance impact of having a header included multiple times: the preprocessor has to go to disk and read the header each time. This can be mitigated by adding guards in your C file to include:
#ifndef FOO_H
#include <foo.h>
#endif
This stuff is discussed in great detail in Large-Scale C++ Software Design (an excellent book).
This is usually solved with preprocessor statements:
#ifndef __STDLIB_H
#include <stdlib.h>
#define __STDLIB_H
#endif
Although I never saw it for common header files like stdlib.h, so it might just be necessary for your own header files.
The preprocessor will include all three copies, but header guards will prevent all but the first copy from being parsed.
Header guards will tell the preprocessor to convert subsequent copies of that header file to effectively nothing.
Response to edit:
Standard library headers will have the header guards. It would be very unusual and incorrect for them to not have the guards.
Similarly, it is your responsibility to use header guards on your own headers.
If header guards are missing, hypothetically, you will get a variety of errors relating to duplicate definitions.
Another point: You can redeclare a function (or extern variable) a bazillion times and the compiler will accept it:
int printf(const char*, ...);
int printf(const char*, ...);
is perfectly legal and has a small compilation overhead but no runtime overhead.
That's what happens when an unguarded include file is included more than once.
Note that it is not true for everything in an include file. You can't redeclare an enum, for example.
This is done by one of the two popular techniques, both of which are under stdlib's responsibility.
One is defining a unique constant and checking for it, to #ifdef out all the contents of the file if it is already defined.
Another is microsoft-specific #pragma once, that has an advantage of not having to even read the from the hard drive if it was already included (by remembering the exact path)
You must also do the same in all header files you produce. Or, headers that include yours will have a problem.
As far a I know regular include simply throws in the contents of another file. The standard library stdlib.h urely utilizes the code guards: http://en.wikipedia.org/wiki/Include_guard, so you end up including only one copy. However, you can break it (do try it!) if you do: #include A, #undef A_GUARD, #include A again.
Now ... why do you include a .h inside another .h? This can be ok, at least in C++, but it is best avoided. You can use forward declarations for that: http://en.wikipedia.org/wiki/Forward_declaration
Using those works for as long as your code does not need to know the size of an imported structure right in the header. You might want to turn some function arguments by value into the ones by reference / pointer to solve this issue.
Also, always utilize the include guards or #pragma once for your own header files!
As others have said, for standard library headers, the system must ensure that the effect of a header being included more than once is the same as the header being included once (they must be idempotent). An exception to that rule is assert.h, the effect of which can change depending upon whether NDEBUG is defined or not. To quote the C standard:
Standard headers may be included in any order; each may be included more than once in
a given scope, with no effect different from being included only once, except that the
effect of including <assert.h> depends on the definition of NDEBUG.
How this is done depends upon the compiler/library. A compiler system may know the names of all the standard headers, and thus not process them a second time (except assert.h as mentioned above). Or, a standard header may include compiler-specific magic (mostly #pragma statements), or "include guards".
But the effect of including any other header more than once need not be same, and then it is up to the header-writer to make sure there is no conflict.
For example, given a header:
int a;
including it twice will result in two definitions of a. This is a Bad Thing.
The easiest way to avoid conflict like this is to use include guards as defined above:
#ifndef H_HEADER_NAME_
#define H_HEADER_NAME_
/* header contents */
#endif
This works for all the compilers, and doesn't rely of compiler-specific #pragmas. (Even with the above, it is a bad idea to define variables in a header file.)
Of course, in your code, you should ensure that the macro name for include guard satisfies this:
It doesn't start with E followed by an uppercase character,
It doesn't start with PRI followed by a lowercase character or X,
It doesn't start with LC_ followed by an uppercase character,
It doesn't start with SIG/SIG_ followed by an uppercase character,
..etc. (That is why I prefer the form H_NAME_.)
As a perverse example, if you want your users guessing about certain buffer sizes, you can have a header like this (warning: don't do this, it's supposed to be a joke).
#ifndef SZ
#define SZ 1024
#else
#if SZ == 1024
#undef SZ
#define SZ 128
#else
#error "You can include me no more than two times!"
#endif
#endif