Force inclusion of a header in project - c++

I have a header with a particular set of rules that the user must follow. If the user does not want to follow the rules, they must define a preprocessor macro which will disable the checks. If the user is using the library, the user must include the header in every one of their classes that uses any code from the library or explicitly state otherwise by the above mentioned preprocessor (in this case, the header may be included implicitly [using one of the library's classes] which is fine):
// User using my library, they must include the BaseHeader.h or otherwise use the following define
// #define NOT_USING_BASE_HEADER //(can of course be defined project wide)
#include <BaseHeader.h>
// ... other includes (not necessarily from my library)
class Foo
{
//...
};
Is there a way to accomplish this? Keep in mind that the base header is also being included

I'm not sure if I understand your question entirely, but do you think this will help?
BaseHeader.h:
#pragma once
#define BASE_HEADER_INCLUDED
...
internal_header.h:
#pragma once
#ifdef NOT_USING_BASE_HEADER
#ifdef BASE_HEADER_INCLUDED
#error You can't both define NOT_USING_BASE_HEADER and include the base-header-file.
#endif
...
#elseif defined BASE_HEADER_INCLUDED
...
#else
#error You have to either define NOT_USING_BASE_HEADER or include the base header file!
#endif
If you want to make it so that it doesn't take "internal" includes of the baseheader.h, then you have to add/remove a define to make sure that it doesn't define it:
internal_header.h:
#pragma once
#define SKIP_HEADER_DEFINE
#include
#undef SKIP_HEADER_DEFINE
And in BaseHeader.h:
#pragma once
#ifndef SKIP_HEADER_DEFINE
#define BASE_HEADER_INCLUDED
#endif
Cheers,
Simon

I see at least two choices:
Document that the users must do this. This needs to be right up front, not buried ten miles deep. You are making any use of your library that doesn't follow your rules undefined behavior (obviously not UB as far as the language is concerned, but as far as your library its UB because you said so).
Do it for them. Make all of your headers #include BaseHeader.h. Don't give the user the option of invoking UB or otherwise screwing up.
BTW, BaseHeader.h is not the best name for a library header. You are asking for name collisions, and that is C++ undefined behavior, and that UB is your fault.

Related

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 put a random number on the first line in header file?

I have seen this countless of times. Instead of
#ifndef _common_h_
#define _common_h_
#endif /* _common_h_ */
people sometimes define their header files in following format:
#ifndef _common_h__479124197491641974591
#define _common_h__479124197491641974591
#endif /* _common_h__479124197491641974591 */
What is that random number good for? I just couldn't successfully google any answer to this.
The idea is to make it harder to trip your include guard unintentionally, and/or to avoid triggering someone elses' include guards.
For example, if you are writing a library, and you have a Common.h header, then using _common_h_ for the guard could prevent users of your library from having _common_h_ guards in their own libraries, which is not ideal. Adding a random number makes such collisions nearly impossible.
The problem
Include guards are often declared in the form:
#ifndef X
#define X
...
#endif
The programmer is free to choose, what we will call here as, a "name". This name is often unique within a single library, but it can happen (even if rare) that two libraries define the same name. This can potentially lead to terrible headaches.
The random numbers
Since the name is often not important outside of the specific file, we can choose (or other tools can do it for us) to include a random number within the name, which will make it much harder to cause name clashes.
#pragma once
You can avoid the problem in another way, by using:
#pragma once
This is a well supported extension, which is compatible with clang, gcc and mvc, as well as many other compilers.

how to #define macro only to specific files?

I have a special macro defined in macro.h, but I want it to be valid only in part of my source files (h/cpp),
how can I do that?
I am afraid that some "bad" user included the macro.h before the source files that must not be familiar with the macro.
how can I prevent it?
It is possible to have macros that are defined only in a files scope by using #undef. E.g. :
#define MACRO 1
int a = MACRO;
#undef MACRO
int b = MACRO; // ERROR
However, this does not work across files unless you rely on the order of includes, which would be bad.
If you want to use macros defined in a macro.h in sources, you could have a second unmacro.h and include that at the end of the source:
// foo.cpp
// other includes
#include "macro.h"
// no other includes!
// contents of the source
#include "unmacro.h"
However, I would not recommended it because it is error-prone. Better reconsider if you need to use macros at all. In modern C++ their valid uses are extremely rare.
You can't. If it's in macro.h, and that file is public, there's no going around it.
A common technique is defining the macro conditionally:
#ifdef SOME_CONDITION
#define MY_MACRO
#endif
but a "bad" user can just as well define SOME_CONDITION.
What you should do is separate public headers from private ones. As you stated the problem, the macro you want hidden probably shouldn't be in a public header at all.
You cannot control the area of effect of the macro, especially if you have it in a .h which is included everywhere.
If you want it to exist only in a few .h and .cpp files then one option is to (re)define it at the top of those cpp files. You could also seperate just these macros into its own .h and include it only in the cpp files that need it and not expose it to users of your code.
You might want to give a more specific example if you want more specific answers

C++ include guard

So I know how to place an include guard in my own header files with the standard
#ifndef ...
#define ...
Now, My question is about including libraries that are not my own. would be a good example. I have a header file which requires the use of string, so I do the following
foo.h
#ifndef FOO_H
#define FOO_H
#include <string>
... code etc ...
#endif
Now, if I have another header file called.. lets say, bar.h, which ALSO requires the use of <string>, how can i prevent multiple inclusions? Does the STL already have include guards in place?
The STL library also has include guards and any good library should do the same.
#ifndef _GLIBCXX_STRING
#define _GLIBCXX_STRING 1
This is from gcc's
Assuming that by "STL" you mean the C++ standard library, then you can refer to the C++ standard. ยง17.6.2.2/2 states:
A translation unit may include library headers in any order. Each may be included more than once, with no effect different from being included exactly once, except that the effect of including either <cassert> or <assert.h> depends each time on the lexically current definition of NDEBUG.
This means that it is not necessary to guard against multiple inclusions of the same header.
Include guard use to guard the content inside the guard pair. You can check the system head file string, it also has the include guard. So, don't worry about multiple inclusions.

Can I redefine a C++ macro then define it back?

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.)