I am a first year computer science student and my professor said #define
is banned in the industry standards along with #if
, #ifdef
, #else
, and a few other preprocessor directives. He used the word "banned" because of unexpected behaviour.
Is this accurate? If so why?
Are there, in fact, any standards which prohibit the use of these directives?
That's completely false, macros are heavily used in C. Beginners often use them badly but that's not a reason to ban them from industry. A classic bad usage is
#define succesor(n) n + 1
. If you expect2 * successor(9)
to give 20, then you're wrong because that expression will be translated as2 * 9 + 1
i.e. 19 not 20. Use parenthesis to get the expected result.No, use of macros is not banned.
In fact, use of
#include
guards in header files is one common technique that is often mandatory and encouraged by accepted coding guidelines. Some folks claim that#pragma once
is an alternative to that, but the problem is that#pragma once
- by definition, since pragmas are a hook provided by the standard for compiler-specific extensions - is non-standard, even if it is supported by a number of compilers.That said, there are a number of industry guidelines and encouraged practices that actively discourage all usage of macros other than
#include
guards because of the problems macros introduce (not respecting scope, etc). In C++ development, use of macros is frowned upon even more strongly than in C development.Discouraging use of something is not the same as banning it, since it is still possible to legitimately use it - for example, by documenting a justification.
No. It is not banned. And truth to be told, it is impossible to do non-trivial multi-platform code without it.
No,
#define
is not banned. Misuse of#define
, however, may be frowned upon.For instance, you may use
#define DEBUG
in your code so that later on, you can designate parts of your code for conditional compilation using
#ifdef DEBUG
, for debug purposes only. I don't think anyone in his right mind would want to ban something like this. Macros defined using#define
are also used extensively in portable programs, to enable/disable compilation of platform-specific code.However, if you are using something like
#define PI 3.141592653589793
your teacher may rightfully point out that it is much better to declare
PI
as a constant with the appropriate type, e.g.,const double PI = 3.141592653589793;
as it allows the compiler to do type checking when
PI
is used.Similarly (as mentioned by John Bode above), the use of function-like macros may be disapproved of, especially in C++ where templates can be used. So instead of
#define SQ(X) ((X)*(X))
consider using
double SQ(double X) { return X * X; }
or, in C++, better yet,
template <typename T>T SQ(T X) { return X * X; }
Once again, the idea is that by using the facilities of the language instead of the preprocessor, you allow the compiler to type check and also (possibly) generate better code.
Once you have enough coding experience, you'll know exactly when it is appropriate to use
#define
. Until then, I think it is a good idea for your teacher to impose certain rules and coding standards, but preferably they themselves should know, and be able to explain, the reasons. A blanket ban on#define
is nonsensical.No your professor is wrong or you misheard something.
#define
is a preprocessor macro, and preprocessor macros are needed for conditional compilation and some conventions, which aren't simply built in the C language. For example, in a recent C standard, namely C99, support for booleans had been added. But it's not supported "native" by the language, but by preprocessor#define
s. See this reference to stdbool.hFirst I've heard of it.
No;
#define
and so on are widely used. Sometimes too widely used, but definitely used. There are places where the C standard mandates the use of macros — you can't avoid those easily. For example, §7.5 Errors<errno.h>
says:Given this, it is clear that not all industry standards prohibit the use of the C preprocessor macro directives. However, there are 'best practices' or 'coding guidelines' standards from various organizations that prescribe limits on the use of the C preprocessor, though none ban its use completely — it is an innate part of C and cannot be wholly avoided. Often, these standards are for people working in safety-critical areas.
One standard you could check the MISRA C (2012) standard; that tends to proscribe things, but even that recognizes that
#define
et al are sometimes needed (section 8.20, rules 20.1 through 20.14 cover the C preprocessor).The NASA GSFC (Goddard Space Flight Center) C Coding Standards simply say:
The discussion after that introductory statement illustrates the acceptable use of function macros.
The CERT C Coding Standard has a number of guidelines about the use of the preprocessor, and implies that you should minimize the use of the preprocessor, but does not ban its use.
Stroustrup would like to make the preprocessor irrelevant in C++, but that hasn't happened yet. As Peter notes, some C++ standards, such as the JSF AV C++ Coding Standards (Joint Strike Fighter, Air Vehicle) from circa 2005, dictate minimal use of the C preprocessor. Essentially, the JSF AV C++ rules restrict it to
#include
and the#ifndef XYZ_H
/#define XYZ_H
/ … /#endif
dance that prevents multiple inclusions of a single header. C++ has some options that are not available in C — notably, better support for typed constants that can then be used in places where C does not allow them to be used. See alsostatic const
vs#define
vsenum
for a discussion of the issues there.It is a good idea to minimize the use of the preprocessor — it is often abused at least as much as it is used (see the Boost preprocessor 'library' for illustrations of how far you can go with the C preprocessor).
Summary
The preprocessor is an integral part of C and
#define
and#if
etc cannot be wholly avoided. The statement by the professor in the question is not generally valid:#define
is banned in the industry standards along with#if
,#ifdef
,#else
, and a few other macros is an over-statement at best, but might be supportable with explicit reference to specific industry standards (but the standards in question do not include ISO/IEC 9899:2011 — the C standard).Note that David Hammen has provided information about one specific C coding standard — the JPL C Coding Standard — that prohibits a lot of things that many people use in C, including limiting the use of of the C preprocessor (and limiting the use of dynamic memory allocation, and prohibiting recursion — read it to see why, and decide whether those reasons are relevant to you).