Macro redefining logical operators

Viewed 187

I'm new to C programming so please forgive me if this sounds like a dumb thing to do.

I had an idea in attempt to make my code a bit more readable and the idea is to #define logical operators such as #define OR ||.

If anyone can direct me is this bad or good practice, is it common etc... and also if it has any side effects, I would be grateful. Thanks in advance.

5 Answers

Alternate names for this and other operators are already part of standard C. Using #include <iso646.h> defines:

Name Replacement
and &&
and_eq &=
bitand &
bitor |
compl ~
not !
not_eq !=
or ||
or_eq |=
xor ^
xor_eq ^=

Don't.

A C coder is expected to read such operators like it was plain English. And also, you would not do the same for the operators +, -, / and *, right? Logicians does not write or. They use symbols. So instead, just get used reading them.

If I saw the expression if(x OR y) in a piece of code, my first thought would be "This must be a beginner" and my next thought would be "Did they do it right and used || or did they use a single |?" I better check this up just to make sure.

is it good practice

My opinion is definitely no

is it common

No, because most C coders share my opinion

and also if it has any side effects

Not really. It's a macro, so it's simple cut and paste.

And just for completeness. It does exist a standard header that does what you want called iso646.h. But it's rarely used. I had never seen it before Eric posted his answer. So if you want to do this, then use that header instead of reinventing the wheel.

  1. Never use Macros without prefix
  2. see the answer of klutt
  3. What's more readable:
  • (a + b) * c
  • (a PLUS b) MULT c

If you want to make code more readable, do that on a higher level, e.g.

if ((x >= y) && (x < z))

implement a function/macro with a meaningful naming, e.g.

#define IN_RANGE(X, MIN, MAX) ((X) >= (MIN)) && ((X) < (MAX))

if (IN_RANGE(x, min, max))
#define logOR ||
#define bitOR |

This may be the one reason why here symbols were chosen, as with + etc. There is not one "or", so it gets lost in a sea of variable names.

side effect:

   if (x||y)
   if (xORy)

The xORy one does not work - unless such variable is declared, which would be very confusing, in combination.


_eq

#define or_eq |=

Now this is actually the argument against it; or= and or = do not work, so good-bye to the assignment operator = also.

a = a PLUS 4   // acceptable - an assignment
a PLUS_EQ 4    // ??? assembler? 

If anyone can direct me is this bad or good practice, is it common etc... and also if it has any side effects, I would be grateful. Thanks in advance.

It is not common practice, and in my experience it creates maintenance problems (such as doing a global search and replace to change an "and" to an "or" in several string literals and breaking code because someone else decided to use and instead of && and or instead of ||).

Straight C code can be a bit eye-stabby, and generations of programmers have tried to use the preprocessor to redefine operators or delimiters to something easier to read (such as Pascal programmers redefining { and } as BEGIN and END, Fortran programmers redefining && and || to AND and OR, etc.). The problem is no two programmers do it the same way, and you just wind up with an unmaintainable mess. Then an experienced C programmer comes in, says "what's all this garbage", and rips it all out anyway, like I wound up doing after the situation I described above.

Resist the urge to create macros for standard delimiters and operators. You just make your code harder to understand and maintain for other C programmers.

Related