Reputation: 9062
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
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
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
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