endif ifndef - what for ?

I know they're processor commands and I read through the definitions but I still don't really understand their purpose? Is there anyone who can explain it in simpler terms :S ?
Last edited on
Well, ifndef, define, and endif are used as header guards.
classHeader.h
1
2
3
4
5
6
#ifndef _CLASSHEADER_H
#define _CLASSHEADER_H

/* ... Code here ... */

#endif 

Header guards are useful to avoid having the code called multiple times in a project. Doing that makes it so if you include classHeader.h in your project, lets say 5 times, the first time it encounters it the preprocessor will see that _CLASSHEADER_H wasn't defined, then define it, load all your code, and end the ifndef call, but when it encounters your header the other 4 times, it will have the _CLASSHEADER_H defined and skip over loading the code the other four times.

There are other uses for them, but that is the most common use for them.
Last edited on
Wow, thank you so much!!! :D I was having such a hard time wrapping my head around this and its uses, but your explanation was perfect.
Last edited on
I'd say that these pre-processor commands are used more often for writing portable code, as opposed to include guards, which can be implemented in other ways than macros.

If I want to write portable code (code which works on other platforms), I'll need to check if certain platform specific macros are defined. Depending on which macros are defined, the compiler will be able to build a working program.

1
2
3
4
5
6
7
8
9
10
//funky pseudo-code
#ifdef __linux__
linuxCode();
#elif defined(_WIN32)
windowsCode();
#elif defined(__APPLE__)
appleCode();
#else
otherCode();
#endif 
[EDIT] @xismn, you replied while I was typing this up. Yeah, I realized
that and wanted to elaborate, but I was trying to think of examples that didn't
throw more preprocessors onto it as I feared it would add to his confusion and
make it more complicated to explain. Hence the terrible examples below and
explanations.

I wanted to build on what I meant by "there are other uses for them".

This code for example is the simplest I could think of.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <iostream>
using namespace std;



int main()
{
	#ifdef DEBUG
		cout << "DEBUGGER CODE!!!\n";
	#endif
	
	#ifndef _DEMO_
		cout << "DEMO code\n";
	#endif
	
	return 0;
}

Let's say I was building this from command line and I had calls to print out some data while it ran so I could test something. I could pass -D (define) to the command line
g++ -o exeFile sourceFile.cpp -DDEBUG
and it will make the ifdef true so that any code I have between #ifdef DEBUG #endif will print out, but because I didn't define _DEMO_ my code there will print out. To remove _DEMO_ from running during compilation I would do
g++ -o exeFile sourceFile.cpp -D_DEMO_ 
making _DEMO_ now defined and will skip over it.

The advantages of this is you can put multiple of them in your code.
1
2
3
4
5
6
7
#ifdef DEBUG
      /* ... */
#endif
      /*.... 100 lines of code */
#ifdef DEBUG
      /* ... */
#endif 


I think the more common place to use them is in libraries for like Allegro, SDL, SFML, etc where they have OS specific macros and functions:
1
2
3
4
5
6
7
#ifdef WIN32
      /* macros and windows pecific functions */
#endif

#ifdef LINUX
      /* macros and linux specific functions */
#endif 


These are just examples to help you get your head around them. If you haven't already you may want to also give this a read: http://www.cplusplus.com/doc/tutorial/preprocessor/
Last edited on
:O ! holy moly, thank you all so much! I really appreciate all of this awesome help
Topic archived. No new replies allowed.