9

I'm reading through a PDF on C++ programming from this page on Stanford's site. It says that when you're creating a C++ header file for a library interface, use a #ifndef preprocessor command to make sure you don't compile the same interface twice.

So, your header would look something like this:

/**
  MyFile.h
*/

#ifndef _MyFile_h
#define _MyFile_h

// Function prototypes

#endif

But, I've always heard people say that using preprocessor commands like #define is (or quickly leads to) bad coding practice. I'm just starting to learn C++, so I don't want to get something ingrained that is bad.

Question: Is it "proper" coding style to use preprocessor commands as above?

2
  • 1
    Whatever you do, don't start 'learning' from the C++ FQA. The whole thing about never using #define sounds like it would come from there.
    – MrFox
    Commented Jun 12, 2013 at 17:21
  • I would also like to point out that, in my opinion, this idea that #defines are bad practice in C++ is simply a myth. Can it lead to ugly code? Sometimes. Is the risk high enough to ban the use of the preprocessor? Never.
    – Dougvj
    Commented Jun 12, 2013 at 20:34

3 Answers 3

17

This is one of the few uses of C++ macros that is widely accepted. It is usually called an include guard. As an alternative, most modern compilers support #pragma once. This is much cleaner, but slightly less portable.

7

There are certain language feature that do get abused by some programmers who have not learned better. Over time, the trend of abuse leads to large consensus of "practice/feature X is bad" and then propagates into an almost a knee-jerk reaction of "OMG I see practice/feature X in this code, this code must be burned"

Global variables or singletons is another great example of this. There is ABSOLUTELY a need to have them and use them WHEN appropriate. The problem is that 98% of code you see out there, these practices should not be used.

As someone who is new to the language you need to learn what each feature does, but don't discount and forget about it just because you heard from somewhere that it is bad. Learn why it is bad and learn to code a better way so you do not need to use it. But after you get through all that, there will absolutely be times when preprocessor is the right answer for certain types of problems.

Biggest problem with preprocessor (besides not being typesafe and all that...) is that people put code in there. Then, maybe a bit more code, then maybe an if-statement. When you debug code with preprocessor, all you see is the point of execution on your macro with no useful idea of what's going on behind it.

As an extreme case, I once worked with a guy who had 200+ line macros. When he needed to debug them, he would copy-paste them directly into the code where the macro was used and remove all '\' from line ends. Then when he was done, he would put the macro back in place, copy-paste all that code back and manually put back all '\' on line ends. Now that is something YOU SHOULD NEVER EVER DO... NEVER :)

1

The thing is called 'internal include guard', and is common practice -- if done well. Your small example manages to have two mistakes:

  • the guard must be full: first to last line. Nothing before and after.
  • beginning with underscore + capital letter is reserved for implementation, so not proper to use, make it MYFILE_H_INCLUDED_, or better like compilers make it, add a GUID. As it must not be repeated in a different .h file. Certainly use

#pragma once is better if supported and can be combined with the include guard.

As the macro name is not used for anything else it will not have its common problems; also except for the pragma there is no real way to allow multiple inclusion of headers, and that is quite needed.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.