These are called guard tags. Guard tags are incredibly helpful when working with header files as they help the programmer by preventing any re-declaration errors when declaring files in a header file.
Let's say for example, I have two classes, one being the parent of the other:
1 2 3 4 5 6 7 8 9 10 11
//IN PARENT.H
#include <iostream>
class Parent
{
private:
int foo, bar;
public:
Parent();
~Parent();
};
1 2 3 4 5 6 7
//IN CHILD.H
#include "Parent.h"
#include <iostream>
class Child : public Parent
{
};
When I did #include "Parent.h" in the child header file, it's as if I am literally copying and pasting everything in Parent.h file into the Child.h file. Therefore, this practically means that I wrote #include <iostream> twice in the Child.h file, which is not good practice.
The guard tags prevent errors that re-declerations like this could cause from happening. With guard tags, I don't need to worry about not re-declaring any files, as they'll make sure there is only one copy of a file where there needs to be:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
//IN PARENT.H
#ifndef PARENT
#define PARENT
#include <iostream>
class Parent
{
private:
int foo, bar;
public:
Parent();
~Parent();
};
#endif /*I personally prefer to write #endif rather than #undef PARENT,
but I believe they are the same thing*/
1 2 3 4 5 6 7 8 9 10 11
//IN CHILD.H
#ifndef CHILD
#define CHILD
#include "Parent.h"
#include <iostream>
class Child : public Parent
{
};
#endif
If you have ever seen the declaration #pragma once made in a header file, these guard tags are the exact same thing. I believe the only difference is that #pragma once isn't a very portable way of doing things.
It's not an include guard (or guard tag as Food 4 Thought like to call them). If you tried to use #undef on an include guard it would make the include guard totally useless because you need the macro to be defined next time the file is included because that is how you keep track of if the file has already been included or not.