Wesley Bland
Wesley Bland

Reputation: 9062

Assign two C preprocessor macros in the same command

Is it possible to assign the same value to two C preprocessor macros at the same time? It would behave similar to this normal C code:

a = b = 1;

I know you can do this:

#define VAR1 1
#define VAR2 1

But that a bit of a pain just because there's now code replication and more opportunity to mess things up. Is the only solution this?

#define VAR1 1
#define VAR2 VAR1

EDIT: As the various comments have pointed out, the preprocessor has macros, not variables. Sorry about that.

Upvotes: 2

Views: 1020

Answers (3)

Kaz
Kaz

Reputation: 58568

The ISO C standard doesn't describe any preprocessing directive which assigns the same replacement sequence to multiple symbols. I.e. this sort of thing doesn't exist in the standard:

// fantasy syntax:
#definemulti (A B C) replacement token sequence

Since replacement sequences can contain multiple tokens, there would have to either have to be parentheses somewhere, or some other way to tell where the names end and the replacement sequence.

In 28 years of C coding, I haven't seen any fragment of code anywhere which required a compiler with such an extension.Even if you find a compiler which has this as an extension, the nonportability of using it is hardly worth it.

Introducing this into the language would probably face hurdles because it saves only a small amount of typing.

Moreover, we can make a technical argument that this is a misfeature.

Say we have several compile-time parameters—A, B, and C—for adjusting the behavior of the code. They happen to have the same value, so we define them in one line.

If later they no longer have the same value, the program has to be edited to split off the different values into separate #define constructs. For instance from this:

#definemulti (A B C) 1

to this

#definemulti (A C) 1
#define B 2

this leads to a line diff which touches A and C. The entire definemulti line is replaced with a new one because B migrated out of it. Under a GNU-style context diff, the change might resemble the following:

@@ -x, y  +z, w @@
 ...
-#define (A B C) 1
+#define (A C) 1
+#define B 2
 ...

Whereas if, in the first place, we have:

#define A 1
#define B 1
#define C 1

the diff hunk is nicer, like this:

@@ -x, y  +z, w @@
 ...
 #define A 1
-#define B 1
+#define B 2
 #define C 1
 ...

At a glance, we see that A and C are unaffected, and that B changed to 2.

We should also consider why we have assignment expressions in of the form lval0 = lval1 = lval2 = ... = val. One big reason is that val is evaluated only once. The expression a = b = c cannot always be rewritten as a = c, b = c due to the change in evaluation order, and multiple evaluation of c.

Upvotes: 3

Potatoswatter
Potatoswatter

Reputation: 137800

If I may extrapolate, it looks like you want two build-configuration macros but usually they should have the same value.

One solution would be to elaborate a little on your last code,

#define VAR1 1         /* May be from a configuration file or makefile. */

/* In the proper source: */
#ifndef VAR2           /* If some configuration is still missing, */
#   define VAR2 VAR1   /* fill in the blank. */
#endif

Now, if you decide to define VAR2 as configuration, it will cancel the default setting inside ifndef.

Upvotes: 0

Tanz87
Tanz87

Reputation: 1294

Looking at the preprocessor syntax, it does not seem like there is a standard way to set both macros together. The syntax allows only one token to be changed into one or more replacement tokens, and allows nothing like operator chaining.

It is also not possible to put two directives in the same line, because a preprocessor directive must end with a newline. There are also no digraphs or trigraphs to inject a newline character before the preprocessor gets to run (as confirmed by a number of prior SO answers).

Upvotes: 0

Related Questions