#ifndef HYS_MAIN_HEADER_H
#define HYS_MAIN_HEADER_H

#include <windows.h>
#include <windowsx.h>

#ifndef HYS_GLOBAL_VARIABLES
#define HYS_GLOBAL_VARIABLES
namespace hys {
	const short Null = 0;
	const bool True = 1;
	const bool False = 0;
};
#endif // HYS_GLOBAL_VARIABLES

#endif // HYS_MAIN_HEADER_H

I want to avoid using macros as much as possible (C++ Coding Standards, by Herb Sutter & Andrei Alexandrescu), so I've decided to try to use my own constant global variables instead of NULL, TRUE, FALSE etc. and see what happens (I'm just trying different ways to do things, it's just an experiment!).

This #ifndef is supposed to check if this namespace was defined before in other files before. It is placed in my main header file.

It does work but I was wondering if this is violating any standards/rules of C++? Can this be a good use of #ifndef, #endif?

Recommended Answers

All 6 Replies

I don't think the conditional on HYS_GLOBAL_VARIABLES is necessary because it is true in exactly the same case that the outer HYS_MAIN_HEADER_H is true. Also, why are you including those windows.h files?

I don't think the conditional on HYS_GLOBAL_VARIABLES is necessary because it is true in exactly the same case that the outer HYS_MAIN_HEADER_H is true. Also, why are you including those windows.h files?

Thanks for your reply.
I thought that "maybe" over time I use this namespace in several header files, so I thought that this needs to be checked for future use. But in general I wanted to know if using #ifndef in this case is acceptable. I'm just trying to learn where and when I can use #ifndef. So, am I doing anything wrong here? Does anyone actually do this?:P

I'm starting a Direct3D application and I'm using windows.h and windowsx.h for creating a window.

There is no need to redefine true/false.

There is no need to redefine true/false.

Thanks for your reply.
It's not about true/false. Let's say this is my code :

#ifndef HYS_MAIN_HEADER_H
#define HYS_MAIN_HEADER_H

#include <something.h>

#ifndef HYS_GLOBAL_VARIABLES
#define HYS_GLOBAL_VARIABLES
namespace hys {
	const float pi = 3.14f;
	const float e = 2.71f;
};
#endif // HYS_GLOBAL_VARIABLES

#endif // HYS_MAIN_HEADER_H

My question is this: Is it wrong to use #ifndef/#endif for this purpose? Is there any other way to check whether these global constants were defined somewhere else before? What is the standard and common way to check for redundancy in this case?

Guarding the header is enough, it guarantees that the header's definitions only appear once. So having a guard inside a guard is useless (not incorrect per se, but useless).

You have to soften your coding standards. Most rules are not that strict, as Sutter and Alexandrescu already point out in their introduction. You are taking a basic guideline of trying to avoid using #defines (because they are harder to maintain and can cause name clashes) to an extreme. You see, the C++ standard committee bends this rule for certain trivial stuff like "NULL" or "TRUE/FALSE", that should tell you that it is totally fine for these universal constants that cannot be mistaken for something else and will never change.

The most blatant coding standard that you are violating here is the fact that you are including headers that are not useful because you assume that any other library that uses your header will also use windows. That breaks rule 23 of the book and is also against the philosophy of rule 59. If you have a bundle of header files that very often all need to get included in many of your other h or cpp files, you can always make a separate header file like "headers_for_this_purpose.h" where you include the bundle of headers (and guard this header too, of course).

@mike_2000_17

Thanks for the answer. As I said from the start "I've decided to try to use my own constant global variables instead of NULL, TRUE, FALSE etc. and see what happens (I'm just trying different ways to do things, it's just an experiment!)"

I changed the code in my question to this:

#ifndef HYS_MAIN_HEADER_H
#define HYS_MAIN_HEADER_H

#include <something1.h>
#include <something2.h>
#include <something3.h>

#ifndef HYS_GLOBAL_VARIABLES
#define HYS_GLOBAL_VARIABLES
namespace hys {
	const float pi = 3.14f;
	const float e = 2.71f;
};
#endif // HYS_GLOBAL_VARIABLES

#endif // HYS_MAIN_HEADER_H

Thank you for pointing out my mistakes. Your answer is exactly what I wanted (Especially rule 59).

So basically none of the above code is necessary. I'll just write the include directive.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.