What is it specifically that is being defined when using #ifndef - c++

What is "ICT_TOOLS_H__"? Is it a header that I'm defining here, or is it a boolean, or an int of 1 or 0? Does the name have to be the same as the header file, or can it be a custom name? Also, do I use #ifndef if the header is included in multiple .cpp files, or should I use it even if it's only #included once? When the compiler goes through the first time, does "ICT_TOOLS_H__" get defined and on every other pass through it doesn't recompile the header, preventing multiple compilations of the same header?
#ifndef ICT_TOOLS_H__ //my proff said to start the name with "ICT_", its the programming department
#define ICT_TOOLS_H__
//implementation goes here
#endif

no it is a macro used for inclusion guard conditional inclusion so at first always this macro is not defined so the condition succeeds and the content is added to the source/header (where included) and in the second time the condition will fail so the content won't be added again.
this is useful when having multiple source/header files where you can include a header twice or more.
//header.h
#ifndef MY_HEADER_H // the name can be anything
#define MY_HEADER_H
// code here (some declarations)
int value;
#endif
//source.cpp
#include "header.h"
#include "header.h"
int main()
{
value = 0; // for example
return 0;
}
if you remove the inclusion guard then the content of header.h will be added twice so as a result two variables value are there and that is a compile-time-error (redefinition).

They are basically macros and are used for conditional compilation.
This is how they work the compile first checks if there is a defined macro called in your case ICT_TOOLS_H__ if it is not defined then the entire code between #ifndef and #endif will compile and as the next line indicates it will define that macro and will be a guard not to compile it again.
If a code compiles more than one time the c++ one definition rule is violated. See here https://en.m.wikipedia.org/wiki/One_Definition_Rule .

Related

Is it legal for a compiler to ignore an #include directive?

As I understand, when compiling a compilation unit, the compiler's preprocessor translates #include directives by expanding the contents of the header file1 specified between the < and > (or ") tokens into the current compilation unit.
It is also my understanding, that most compilers support the #pragma once directive guarding against multiply defined symbols as a result of multiple inclusion of the same header. The same effect can be produced by following the include guard idiom.
My question is two-fold:
Is it legal for a compiler to completely ignore an #include directive if it has previously encountered a #pragma once directive or include guard pattern in this header?
Specifically with Microsoft' compiler is there any difference in this regard whether a header contains a #pragma once directive or an include guard pattern? The documentation suggests that they are handled the same, though some user feels very strongly that I am wrong, so I am confused and want clarification.
1 I'm glossing over the fact, that headers need not necessarily be files altogether.
It the compiled program cannot tell whether the compiler has ignored a header file or not, it is legal under the as-if rule to either ignore or not ignore it.
If ignoring a file results in a program that has observable behaviour different from a program produced by processing all files normally, or ignoring a file results in an invalid program whereas processing it normally does not, then it is not legal to ignore such file. Doing so is a compiler bug.
Compiler writers seem to be confident that ignoring a once-seen file that has proper include guards in place can have no effect on the resulting program, otherwise compilers would not be doing this optimisation. It is possible that they are all wrong though, and there is a counterexample that no one has found to date. It is also possible that non-existence of such counterexample is a theorem that no one has bothered to prove, as it seems intuitively obvious.
I think you can treat #pragma once as compiler language extension like for instance #pragma omp parallel that can make a loop execute in parallel causing all kinds of UB if it is not written correctly.
The standard says it is ok for pragma directive to cause implementation-defined non-conforming result:
Pragma directive [cpp.pragma]
...
causes the implementation to behave in an implementation-defined manner. The behavior might cause
translation to fail or cause the translator or the resulting program to behave in a non-conforming manner.
Any pragma that is not recognized by the implementation is ignored.
Regarding MSVC behavior you can think of it skipping the header based on its normalized path.For instance you can trick the compiler with symlinks:
test/test.h
#pragma once
static int x = 2;
Create symlink "test-link" to "test" directory:
mklink /d test-link test
Then in main.cpp:
#include "test/test.h"
#include "test/test.h"
#include "test/../test/test.h"
is ok. but
#include "test/test.h"
#include "test-link/test.h"
causes
error C2374: 'x': redefinition; multiple initialization
which would not happen in case of include guards.
Is it legal for a compiler to completely ignore an #include directive if it has previously encountered a #pragma once directive or include guard pattern in this header?
That depends on how #pramga once is defined and implemented by the compilers. It is after all a none standard feature.
But, all compilers I know that support #pramga once treat it like a non-mutable unique include guard that wraps around the complete file.
After the preprocessor resolved the include path for an include, it can check if that file was already included and if #pargma once exists for that file. If both conditions are true, it is safe to not include the file anymore, because it would follow the as-if rule, as the compiler vendor is in full controller over how the #pramga once is implemented and can ensure that the lock guard is unique, non-mutable, and wraps the whole file, and due to that a repeated inclusion of that same wile would result in an empty content that is included.
So with that respect, if they didn't make an implementation error it is safe to then ignore the include.
There is the argument against the usage of #pragma once that says that the compiler might treat the same file as different files due to symlinks and hard links. That would result in accidentally including the same file multiple times, but that won't affect the part of whether it is safe to ignore it if the compile identified it as the same file.
Specifically with Microsoft' compiler is there any difference in this regard whether a header contains a #pragma once directive or an include guard pattern? The documentation suggests that they are handled the same, though some user feels very strongly that I am wrong, so I am confused and want clarification.
If no #pragma once is used it becomes more complicated. The preprocessor needs to first check if the lock guard wraps around all contents:
#ifndef SOME_GUARD_NAME_H
#define SOME_GUARD_NAME_H
// all content of the file
#endif
Or if it is something like this:
// some content before the guard
#ifndef SOME_GUARD_NAME_H
#define SOME_GUARD_NAME_H
// some content
#else
// some more content
#endif
// some other content after the guard
And it needs to keep track of whether the SOME_GUARD_NAME_H was already defined in another file or if #undef was called by another file.
So in that case it can only ignore the content of the file if it can ensure that all relevant defines are the same and/or if the evaluation of the macros results in an empty file.
Is it legal for a compiler to completely ignore an #include directive if it has previously encountered a #pragma once directive or include guard pattern in this header?
Of course it is! It is even legal for the compiler to ignore all your source files and header files so long as behavior of the generated code is the same as if it processed everything. That's how pre-compiled headers and object files work - anything that hasn't changed can be safely ignored. Similarly, if the compiler can prove that including and not including the file are going to have exactly the same behavior, the compiler may ignore the file, regardless of the pre-processor directives.
Specifically with Microsoft' compiler is there any difference in this regard whether a header contains a #pragma once directive or an include guard pattern?
The documentation is pretty clear on that. They are identical assuming the compiler manages to identify the idiom and you haven't #undefed the macro. I've never experienced any bugs related to that either. #pragma once is safer though. I have had an instance where two headers had the same include guard and debugging that wasn't a nice experience.
#pragma once obviously refers to the file as a whole
The use of #pragma once can reduce build times, as the compiler won't
open and read the file again after the first #include of the file in
the translation unit.
really - if not to file - for what it can be related ?
the conditional compilation , so called guard idiom related not to file but to block of code. really - where, how stated that some condition related to file ?!
it related to block beginning with #if* and ended with #endif. compiler anyway need include this file again.
let do some tests. also here will be very useful cl(msvc) compiler option /showIncludes
let create header.h
// header.h
#ifndef HEADER_H_
#define HEADER_H_
int g_a = 0;
#endif
and then
#include "header.h"
#include "header.h"
only once in log
1>Note: including file: .\header.h
so header.h really included only once here.
but if do this
// header.h
#if !defined HEADER_H_
#define HEADER_H_
int g_a = 0;
#endif
or this
#if !defined(HEADER_H_)
#define HEADER_H_
int g_a = 0;
#endif
and
#include "header.h"
#include "header.h"
already 2 lines in log - header.h included 2 time.
1>Note: including file: .\header.h
1>Note: including file: .\header.h
so #ifndef HEADER_H_ have different effect compare #if !defined(HEADER_H_)
or if do
// header.h
#ifndef HEADER_H_
#define HEADER_H_
int g_a = 0;
#endif
#define XYZ
or
// header.h
#if __LINE__ // any not empty statement
#endif
#ifndef HEADER_H_
#define HEADER_H_
int g_a = 0;
#endif
and
#include "header.h"
#include "header.h"
already
1>Note: including file: .\header.h
1>Note: including file: .\header.h
again 2 lines in log - header.h included 2 time.
so if exist any not empty ( comments, sequences of whitespace characters (space, tab, new-line)) statement outside first conditional block - file already included more times.
of course possible and do next
// header.h
#include "header.h"
#undef HEADER_H_
#include "header.h"
in this case
1>Note: including file: .\header.h
1>Note: including file: .\header.h
1>.\header.h(4): error C2374: 'g_a': redefinition; multiple initialization
1>.\header.h(4): note: see declaration of g_a'
and of course in case
// header.h
#pragma once
int g_b = 0;
and
#include "header.h"
#include "header.h"
only single line
1>Note: including file: .\header.h
so based on tests can make next conclusion - if cl(msvc) - view that file have pattern
#ifndef macro // but not #if !defined macro
#define macro
// all code only here
#endif
macro associates with the file and then as long as it is not undefined - the file will not be included more. this is implicit optimization by specific compiler. and very fragile. any not white space or comment statement break it. even despite documented that #ifndef HEADER_H_ quivalently to #if !defined HEADER_H_ - by fact this is not true.

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

Header guard in c++ [duplicate]

At LearnCpp.com | 1.10 — A first look at the preprocessor. Under Header guards, there are those code snippets:
add.h:
#include "mymath.h"
int add(int x, int y);
subtract.h:
#include "mymath.h"
int subtract(int x, int y);
main.cpp:
#include "add.h"
#include "subtract.h"
In implementing the header guard, it is mentioned as follows:
#ifndef ADD_H
#define ADD_H
// your declarations here
#endif
What could the declaration be here? And, should int main() come after #endif?
Is adding _H a convention or a must do thing?
Thanks.
The FILENAME_H is a convention. If you really wanted, you could use #ifndef FLUFFY_KITTENS as a header guard (provided it was not defined anywhere else), but that would be a tricky bug if you defined it somewhere else, say as the number of kittens for something or other.
In the header file add.h the declarations are literally between #ifndef and #endif.
#ifndef ADD_H
#define ADD_H
#include "mymath.h"
int add(int x, int y);
#endif
Finally, int main() shouldn't be in a header file. It should always be in a .cpp file.
To clear it up:
#ifndef ADD_H basically means "if ADD_H has not been #defined in the file or in an included file, then compile the code between #ifndef and #endif directives". So if you try to #include "add.h" more than once in a .cpp file, the compiler will see what the ADD_H was already #defined and will ignore the code between #ifndef and #endif. Header guards only prevent a header file from being included multiple times in the same .cpp file. Header guards don't prevent other .cpp files from including the header file. But all .cpp files can include the guarded header file only once.
The result of preprocessing one implementation (".cpp") file is a translation unit (TU).
Headers can include other headers, so a header may be indirectly included multiple times within the same TU. (Your mymath.h is an example of this.)
Definitions can only occur at most once per TU. (Some definitions must also not be in multiple TUs; this case is slightly different and not discussed here.)
The problem include guards solve is preventing multiple definition errors when a given header is included more than once within one TU.
Include guards work by "wrapping" the contents of the header in such a way that the second and subsequent includes are no-ops. The #ifndef/#define directives should be the first two lines of the file, and #endif should be the last.
Include guards are only used in headers. Do not define your main function in a header: put it in an implementation file.
If you have a header that will define a type and declare a function, but also needs a header itself:
#include "other_header.h"
struct Example {};
void f();
"Wrapping" it with include guards gives the complete contents of the file:
#ifndef UNIQUE_NAME_HERE
#define UNIQUE_NAME_HERE
#include "other_header.h"
struct Example {};
void f();
#endif
The name used for the include guard must be unique, otherwise conflicting names will give confusing results. These names are only simple macros, and there is nothing in the language which enforces a certain style. However, project conventions usually impose requirements. There are several different include guard naming styles you can find here on SO and elsewhere; this answer gives good criteria and a good overview.
All the header guards do is to only allow your headers to be included once. (If they're included multiple times, they're ignored.)
The name you use doesn't matter, but it's conventional to use the file name in caps, including the extension like you demonstrated.
Your main should really be in a .cpp file, but if you're putting it in a header, put it inside the guards so it isn't declared multiple times.
No, the int main() goes in a .cpp. The declarations are the other stuff you were gonna put in the header. _H is a convention, you can see various header guard conventions around.
I declare a declaration in header file and definitions or int main() comes in source.cpp file.
_H is there to merely indicate that someone is going to include header files using include guards.
If you're on MSVC++ you can also use #pragma once

Include Guards and #ifndef #define Preprocessing Statements

If I do the following:
dConst.hpp
const int POWER_LEVEL = 9001;
genPower.hpp
#include "dConst.hpp"
#ifndef GENPOWER_HPP
#define GENPOWER_HPP
const int GENERATOR[1] = { POWER_LEVEL };
#endif
I end up getting linker errors for any code that utilizes the generator array constant.
However, if I switch the #include "dConst.hpp" with the code block:
#ifndef GENPOWER_HPP
#define GENPOWER_HPP
It works...
Am I misusing the power of the #ifndef?
You are under-using the power of #ifndef.
Your dConst.hpp file needs include guards. Otherwise, it will cause problems (the exact problems you saw) if it is included from more than one file within a translation unit.
EDIT: I would also place your include guards in genPower.hpp at the top of the file, before your include statements.
Yes, definitely.
The point of include guards is to make sure your code doesn't get included twice - if you have some code in your header files that's not inside the include guard, if you include that header twice, you're defining everything outside the guards twice.
For a bit of a better idea of what's going on, your generated code looks something like this:
The #include basically just inserts the contents of the included file directly into the other file in place, meaning that your genPower.hpp looks like this (without the include guards in place properly, like you have originally in your question):
const int POWER_LEVEL = 9001;
#ifndef GENPOWER_HPP
#define GENPOWER_HPP
const int GENERATOR[1] = { POWER_LEVEL };
#endif
Therefore, every time you include that file, before the #ifndef gets reached, POWER_LEVEL gets defined. If you switch the POWER_LEVEL lines with the #ifndef/#define, every time you include this file, it will first CHECK if it's already been included (with the #ifndef - if it's already been included, the #define should have done its work) and ONLY THEN (once it's figured out this is the first time) will it define POWER_LEVEL.
Also, you almost definitely want include guards on your dConst.hpp as well - ALL headers should have include guards, and they should guard EVERYTHING in the header file. That's your mistake with #ifndef.

Header guards in C++ and C

At LearnCpp.com | 1.10 — A first look at the preprocessor. Under Header guards, there are those code snippets:
add.h:
#include "mymath.h"
int add(int x, int y);
subtract.h:
#include "mymath.h"
int subtract(int x, int y);
main.cpp:
#include "add.h"
#include "subtract.h"
In implementing the header guard, it is mentioned as follows:
#ifndef ADD_H
#define ADD_H
// your declarations here
#endif
What could the declaration be here? And, should int main() come after #endif?
Is adding _H a convention or a must do thing?
Thanks.
The FILENAME_H is a convention. If you really wanted, you could use #ifndef FLUFFY_KITTENS as a header guard (provided it was not defined anywhere else), but that would be a tricky bug if you defined it somewhere else, say as the number of kittens for something or other.
In the header file add.h the declarations are literally between #ifndef and #endif.
#ifndef ADD_H
#define ADD_H
#include "mymath.h"
int add(int x, int y);
#endif
Finally, int main() shouldn't be in a header file. It should always be in a .cpp file.
To clear it up:
#ifndef ADD_H basically means "if ADD_H has not been #defined in the file or in an included file, then compile the code between #ifndef and #endif directives". So if you try to #include "add.h" more than once in a .cpp file, the compiler will see what the ADD_H was already #defined and will ignore the code between #ifndef and #endif. Header guards only prevent a header file from being included multiple times in the same .cpp file. Header guards don't prevent other .cpp files from including the header file. But all .cpp files can include the guarded header file only once.
The result of preprocessing one implementation (".cpp") file is a translation unit (TU).
Headers can include other headers, so a header may be indirectly included multiple times within the same TU. (Your mymath.h is an example of this.)
Definitions can only occur at most once per TU. (Some definitions must also not be in multiple TUs; this case is slightly different and not discussed here.)
The problem include guards solve is preventing multiple definition errors when a given header is included more than once within one TU.
Include guards work by "wrapping" the contents of the header in such a way that the second and subsequent includes are no-ops. The #ifndef/#define directives should be the first two lines of the file, and #endif should be the last.
Include guards are only used in headers. Do not define your main function in a header: put it in an implementation file.
If you have a header that will define a type and declare a function, but also needs a header itself:
#include "other_header.h"
struct Example {};
void f();
"Wrapping" it with include guards gives the complete contents of the file:
#ifndef UNIQUE_NAME_HERE
#define UNIQUE_NAME_HERE
#include "other_header.h"
struct Example {};
void f();
#endif
The name used for the include guard must be unique, otherwise conflicting names will give confusing results. These names are only simple macros, and there is nothing in the language which enforces a certain style. However, project conventions usually impose requirements. There are several different include guard naming styles you can find here on SO and elsewhere; this answer gives good criteria and a good overview.
All the header guards do is to only allow your headers to be included once. (If they're included multiple times, they're ignored.)
The name you use doesn't matter, but it's conventional to use the file name in caps, including the extension like you demonstrated.
Your main should really be in a .cpp file, but if you're putting it in a header, put it inside the guards so it isn't declared multiple times.
No, the int main() goes in a .cpp. The declarations are the other stuff you were gonna put in the header. _H is a convention, you can see various header guard conventions around.
I declare a declaration in header file and definitions or int main() comes in source.cpp file.
_H is there to merely indicate that someone is going to include header files using include guards.
If you're on MSVC++ you can also use #pragma once