Click here to Skip to main content
15,880,543 members
Articles / Programming Languages / C
Tip/Trick

Symbolic Code Isn't Always Meaningful

Rate me:
Please Sign up or sign in to vote.
4.93/5 (9 votes)
18 Mar 2019CPOL2 min read 9.5K   1   9
Overuse of #define can be ludicrous.

Introduction

We rightly provide meaningful names to numeric and string constants in our code for a variety of good reasons. For example, it's much easier to remember and use the name SPI1 than it is to use the pointer value 0x40013000, and it's much nicer, too, when porting the code to a device where SPI1 is at address 0x40014000 instead: we change the definition once and the rest of our code is magically brought up to date.

But...

Let's Not Go Overboard

C++
#ifndef ZERO
#define ZERO 0 
#endif

#ifndef ONE 
#define ONE !ZERO 
#endif

I stumbled over this in production code today. The sheer foolishness of these six lines of code baffles me. Let's look at...

Why This Is Wrong

This is a perfect example of cargo cult programming. Someone chose to follow "best practices" without understanding why they're best practices and when they should not apply.

This person heard you should always wrap your #defines in protection blocks, so they've #ifndef-protected their definition of ZERO. You know, in case someone defines ZERO to be any value other than 0... (Because #define ZERO 17 would never be confusing!)

Naturally, they've done the same for ONE. In case someone had already done #define ONE 2301331...

But that's not where the oddness ends.

Look again at how ONE is defined: !ZERO. A numerical value is being defined in terms of a logical operator. This isn't just confusing. This is dangerous. You cannot make any assumptions about logical operations in C. !ZERO expands to !0 which may not necessarily be 1 in every compiler. Even if the standard defines !0 to be 1, it's not a safe thing to assume. I've been programming in C since before there was a C standard. I've never encountered a compiler that was 100% standards-compliant...

But all that's beside the point because...

Here's How to Do It Right

How do you do this right? Use the constants 0 and 1. It's that simple. Zero will NEVER be defined as any value other than 0 and one will never be defined as any value other than 1. There is no programmer on Earth that will look at 0 and wonder what it is. The same applies to 1. (This does not apply to ZERO and ONE!) You save typing. You make things clearer. And you don't have to worry about standards compliance. (If your compiler is confusing 0 and 1 in calculations with other numbers, you have bigger problems than following "best practices" to worry about!).

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
China China
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
GeneralSeen it too Pin
Chad3F23-Mar-19 7:45
Chad3F23-Mar-19 7:45 
SuggestionDon't use macros. At all! Pin
Stefan_Lang21-Mar-19 22:51
Stefan_Lang21-Mar-19 22:51 
GeneralRe: Don't use macros. At all! Pin
qqmrichter22-Mar-19 0:20
qqmrichter22-Mar-19 0:20 
GeneralRe: Don't use macros. At all! Pin
Stefan_Lang22-Mar-19 4:13
Stefan_Lang22-Mar-19 4:13 
GeneralRe: Don't use macros. At all! Pin
qqmrichter28-Mar-19 20:16
qqmrichter28-Mar-19 20:16 
GeneralRe: Don't use macros. At all! Pin
Stefan_Lang28-Mar-19 22:35
Stefan_Lang28-Mar-19 22:35 
QuestionAnd it gets even worse... Pin
Stacy Dudovitz19-Mar-19 15:36
professionalStacy Dudovitz19-Mar-19 15:36 
Questionuse of macros in c++ Pin
Member 1417446019-Mar-19 1:53
professionalMember 1417446019-Mar-19 1:53 
I agree that the #define in the article is not helpful, however if you wanted to define One as 1 the best way to do it is a constexpr variable not via #define.

constexpr int one = 1;

Macros are glorified text substitution mechanisms and as such circumvent the type mechanism of C++

See https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#Res-macros2
AnswerRe: use of macros in c++ Pin
qqmrichter28-Mar-19 20:22
qqmrichter28-Mar-19 20:22 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.