#ifndef ?

I've quoted the following

"The #ifndef directive shown in the rectangle.h header file is called an
include guard and prevents a header file from accidentally being included
more than once. In the rectangle.h file, the #ifndef directive checks for the
existence of a constant, RECTANGLE_H. If the constant has not been defined, it
is immediately defined and the file is included. If the constant has already
been defined, everything between the #ifndef and #endif directives is
skipped."

from this book Starting Out with C++ by Tony Gaddis.

My question is what will happen if the header file being included more than once? What are the errors may I get?
Header guards exist to make sure that a file's contents are only seen once by the compiler. If the compiler sees a function or class declaration more than once, it gives an error:
1
2
3
4
5
6
7
8
9
10
// Bad:
int intFunc (int);
int intFunc (int);

// Good:
void voidFunc (void);
void voidFunc (void)
{
// do something
}


The header guard stops this behaviour by only letting the compiler see the header's contents once. It won't give any errors, it will prevent them
@theranga
Thank you. I've eliminated #ifndef and I haven't get any error. Is it mandatory to include them? Or we add them just in case?
It's not mandatory, but you should always do it.

I explain the reasons in this article. Specifically, see section 3 "Include Guards":

http://www.cplusplus.com/forum/articles/10627/#msg49679
@Disch,
Thank you so much. This is what I'm looking for. It is very informative and helpful. I have another question and I'm quit certain you are capable to answer. Hopefully!
I've posted this question in this forum. Some people answered it but I still not get it. Sometimes i would like to add a library for example OpenCV or OpenGL. These have header files and I have to link them to my project or my IDE. My question is is there any book explains the idea? What is going on in the background. How does the compiler do the stuff? I really got tired following some bad tutorials and in the end getting a lot of errors. I wanna add OpenCV library in qt in mac and I'm facing numerous problems just because I'm not familiar with the idea of adding a library to my project.
I can't really recommend any books... but I suppose I can try to explain what's happening.

I assume you understand the difference between a header file and a source file. When you build (compile+link) an EXE, each source file is compiled independently forming an intermediate "object" file. This object file is compiled code, but can't be executed because it's somewhat incomplete.


For example, given the below program:
1
2
3
// header.h

void func();

1
2
3
4
5
6
7
8
// func.cpp
#include <iostream>
#include "header.h"

void func()
{
  std::cout << "hello world";
}

1
2
3
4
5
6
7
8
// main.cpp

#include "header.h"

int main()
{
  func();
}


When this program is compiled, 2 object files are formed (either with the .obj extension, or the .o, or something else -- it depends on what compiler you're using). One for each source file.

main.obj would contain the compiled code for the main() function. However it cannot be executed because it tries to call the 'func' function, and the code for that is not in main.obj. The compiled code for the 'func' function is over in func.obj.


The next step is the linker, which takes all those .obj files and links them to form the final executable. In this case, the references main.obj makes to the func function will be filled in by linking it to func.obj.



So what does this have to do with libraries? Well libraries are built the exact same way. The only difference is they form a static lib or dll instead of an exe. But the concept is the same.

Something like OpenGL is a massive library with a ton of compiled code. Including the header will define the functions for the compiler, but those functions will remain 'unresolved' to the linker because they have no body. The body for those functions are in the library itself.

So that's why you need to add a linker reference to a library when you use it. That tells the linker to use that library to fill in the bodies for those functions.
@theranga: It is perfectly valid to forward declare a function multiple times, just as it is valid to forward declare a class or global variable multiple times, so long as the definitions match:
1
2
3
4
5
6
7
8
9
10
11
12
int f();
int f(); //fine, matches
int f(int); //different signature, fine
float f(); //error: return type does not match

class c;
class c; //fine, matches
struct c; //wrong: does not match

extern int x; //syntactically fine, but completely evil
extern int x; //syntactically still fine, but still completely evil
extern float x; //syntactically wrong, and just as evil 
http://ideone.com/iy9Pnz (the class/struct thing will give you warnings, not errors)

The reason you include guard headers is because of the class definitions, which can appear multiple times overall but only once per CPP file.
Last edited on
@Disch,
Thank you so much. I like the way you explain these complicated concepts. What is the difference between cpp and header files in Debug mode and Release mode? After creating object files, waiting the linker to link them to create exe file, Does the linker distinguish between Debug mode and Release mode?

Thank you so much in advance.
What is the difference between cpp and header files in Debug mode and Release mode?


There is no 'difference' in terms of code. Debug generally just puts in extra information so if you debug the program you can see variable names, function names, etc. It usually also removes optimizations so the code is more closely followed when you step through it. Release is basically the opposite.

After creating object files, waiting the linker to link them to create exe file, Does the linker distinguish between Debug mode and Release mode?


I don't think it has to but it might...Not totally sure on this part.
@firedraco,

Thank you so much. What do you mean by saying in Debug mode I can see variable names, function names?
When you build in Release mode, there is no reason to store information such as the names of variables; it would just take up space in the executable. However, when you want to see what is causing a crash or glitch, you use a debugger, and the debugger needs the names of those variables to be helpful to you, so you build in Debug mode to keep that information.

Build in Debug mode also adds in extra checks to things in code that aren't normally there in Release mode because the program runs faster without making those checks, for instance checking that you are not accessing an element in a list that does not exist.
Last edited on
There are programs called 'debuggers' that let you step through your C++ code basically and see what values variables and such have at each step. If you have debugging information the debugger can tell you the names of the variables or functions, among other things.
@L B & firedraco,
thank guys so much for being helpful and patient.
Topic archived. No new replies allowed.