I have a code base which uses #define in a different way then I am accustomed to.
I know that, for example, #define a 5 will replace variable a with 5 in the code.
But what would this mean:
'#define MSG_FLAG 5, REG, MSGCLR'
I tried doing it in a simple code and compiling it. It takes the last value (like the third argument as MSGCLR).
Preprocessing is largely just string replacement that happens before the "real" compilation starts. So we don't have any idea of what a variable is at this point.
The commas here are not any special syntax. This will cause any appearance of MSG_FLAG in the code to be replaced by 5, REG, MSGCLR
Most compilers have a flag that will just run the preprocessor, so you can see for yourself. On gcc, this is -E.
So to verify this, we can have some nonsense source:
#define MSG_FLAG 5, REG, MSGCLR
MSG_FLAG
Compile with gcc -E test.c
And the output is:
# 1 "test.c"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "test.c"
5, REG, MSGCLR
Related
Here's a simple little C program that had me confused for a while:
#include <stdio.h>
#define STR1(x) #x
#define STR(x) STR1(x)
int main(void) {
printf("%s\n", STR(MYDEF));
}
This just prints the value of the MYDEF #define as a string, using the standard stringizing double-define technique.
Compile (on Linux) with gcc -DMYDEF=abc prog.c run the result and, not surprisingly, it prints out 'abc'.
But change the value gcc -DMYDEF=linux prog.c and the result printed is not 'linux' but '1'.
So that confused me for a bit, but of course it happens because gcc (on Linux) has, I discovered, a built-in #define for the name 'linux' with a value '1', and the STR(x) macro ends up expanding MYDEF to 'linux' then linux to '1'.
In my real program (which was rather more complex than the little test above) I got round this by doing things in a different (probably better) way, but it left me curious ... is there a simple little macro technique that would avoid this double-substitution and make the program print out 'linux'? I know I could add a -U or #undef of linux, but that feels a bit clumsy.
I had thought all the built-in #defines start with underscores (usually double underscores), but I guess not.
There is no way to expand a macro only once, there's always a rescan performing further replacement (never recursive, of course). There are circumstances where macros aren't expanded at all (as with the # operator), which is why you need the extra replacement level with two #define like in your example.
In ISO C, identifiers without a leading underscore are free for you to use (not all of them, to be precise). The GNU C dialects define some other macros by default (like linux) for backwards compatibility, though they plan to remove such macros in the future.
To get a list of such macros on your machine, you can do:
$ echo | gcc -std=gnu99 -E -dM - | grep -v '# *define *_'
#define unix 1
#define linux 1
#define i386 1
With the options for ISO C (-ansi/-std=c89, -std=c99, -std=c11/-std=c1x for older Gcc), these macros are not defined:
$ cat test.c
#define STR1(x) #x
#define STR(x) STR1(x)
STR(MYDEF);
STR1(MYDEF);
$ gcc -std=gnu99 -DMYDEF=linux -E test.c
# 1 "test.c"
# 1 "<command-line>"
# 1 "test.c"
"1";
"MYDEF";
$ gcc -std=c99 -DMYDEF=linux -E test.c
# 1 "test.c"
# 1 "<command-line>"
# 1 "test.c"
"linux";
"MYDEF";
In ISO C mode, these macros properly are in the reserved namespace:
$ echo | gcc -std=c99 -E -dM - | grep linux
#define __linux 1
#define __linux__ 1
#define __gnu_linux__ 1
I see in the gcc manual that you can use the -ansi option to turn off predefined macros like "linux"
gcc -ansi -DMYDEF=linux prog.c
I'm attempting to refactor a piece of legacy code and I'd like a snapshot of all of the macros defined at a certain point in the source. The code imports a ridiculous number of headers etc. and it's a bit tedious to track them down by hand.
Something like
#define FOO 1
int myFunc(...) {
PRINT_ALL_DEFINED_THINGS(stderr)
/* ... */
}
Expected somewhere in the output
MACRO: "FOO" value 1
I'm using gcc but have access to other compilers if they are easier to accomplish this task.
EDIT:
The linked question does not give me the correct output for this:
#include <stdio.h>
#define FOO 1
int main(void) {
printf("%d\n", FOO);
}
#define FOO 0
This very clearly prints 1 when run, but gcc test.c -E -dM | grep FOO gives me 0
To dump all defines you can run:
gcc -dM -E file.c
Check GCC dump preprocessor defines
All defines that it will dump will be the value defined (or last redefined), you won't be able to dump the define value in all those portions of code.
You can also append the option "-Wunused-macro" to warn when macros have been redefined.
I'm currently writing code for a microcontroller; since the ATMega128 does not have a hardware multiplier or divider, these operations must be done in software and they take up a decent amount of cycles. However, for code portability and ease of use, I'd prefer not to hard-code precomputed values into my code So for instance, I have a number of tasks which are dependent on the system clock frequency. Currently I' running at 16MHz, but should I choose to lower that, say to reduce power consumption for battery applications, I'd like to change one line of code rather than many.
So with that said, can the C preprocessor compute arithmetic expressions and then "paste" the result into my code rather than "pasting" the original expression into the code? If so, how would I go about doing this? Are their compiler options and whatnot that I need to consider?
NOTE: The values I want to compute are constant values, so I see no reason why this would not be a feature.
This is one question:
Q1. Can the C preprocessor perform arithmetic?
And this is another:
Q2. Can the C preprocessor compute arithmetic expressions and then "paste"
the result into my code rather than "pasting" the original expression into the code?
The answer to Q1 is Yes. The answer to Q2 is No. Both facts can be illustrated
with the following file:
foo.c
#define EXPR ((1 + 2) * 3)
#if EXPR == 9
int nine = EXPR;
#else
int not_nine = EXPR;
#endif
If we pass this to the C preprocessor, either by cpp foo.c or
equivalently gcc -E foo.c, we see output like:
# 1 "foo.c"
# 1 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 30 "/usr/include/stdc-predef.h" 3 4
# 1 "/usr/include/x86_64-linux-gnu/bits/predefs.h" 1 3 4
# 31 "/usr/include/stdc-predef.h" 2 3 4
# 1 "<command-line>" 2
# 1 "foo.c"
int nine = ((1 + 2) * 3);
The fact that the preprocessor retains the line defining int nine and
has dropped the line defining not_nine shows us that it has correctly performed
the arithmetic required to evaluate #if EXPR == 9.
The fact that the preprocessed text of the definition is int nine = ((1 + 2) * 3);
shows us that the #define directive causes the preprocessor to replace
EXPR with its definition ((1 + 2) * 3), and not with the arithmetic value
of its definition, 9.
Does the C preprocessor have any directive besides #define which has the second
effect? No.
But this does not of course imply that the definition of int nine must entail a
runtime calculation, because the compiler will almost certainly evaluate
the arithmetic expression ((1 + 2) * 3) at compiletime and replace it with
the constant 9.
We can see how the compiler has translated the source file by examining the
compiled object file. Most toolchains will provide something like GNU binutils
objdump to assist with this. If I compile foo.c with gcc:
gcc -c -o foo.o foo.c
and then invoke:
objdump -s foo.o
to see the full contents of foo.o, I get:
foo.o: file format elf64-x86-64
Contents of section .data:
0000 09000000 ....
Contents of section .comment:
0000 00474343 3a202855 62756e74 752f4c69 .GCC: (Ubuntu/Li
0010 6e61726f 20342e38 2e312d31 30756275 naro 4.8.1-10ubu
0020 6e747539 2920342e 382e3100 ntu9) 4.8.1.
And there is the hoped-for 9 hard-coded in the .data section.
Note that the preprocessor's arithmetic capabilities are restricted to integer arithmetic
It can, but is unnecessary: you don't actually need to involve the preprocessor unless you actually want to generate new identifiers that involve numbers in some way (e.g. stuff like func1, func2).
Expressions like 1 + 2 * 3, where all elements are compile-time constant integer values, will be replaced with the single result at compile-time (this is more or less demanded by the C standard, so it's not "really" an optimisation). So just #define constants where you need to name a value that can be changed from one place, make sure the expression doesn't involve any runtime variables, and unless your compiler is intentionally getting in your way you should have no runtime operations to worry about.
Yes you can do arithmetic using the preprocessor, but it takes a lot of work. Reading this page here, shows how to create an increment counter, and a while loop. So with that you could create addition:
#define ADD_PRED(x, y) y
#define ADD_OP(x, y) INC(x), DEC(y)
#define ADD(x, y) WHILE(ADD_PRED, ADD_OP, x, y)
EVAL(ADD(1, 2)) // Expands to 3
So reusing the ADD macro you can then create a MUL macro something like this:
#define MUL_PRED(r, x, y) y
#define MUL_OP(r, x, y) ADD(r, x), x, DEC(y)
#define MUL_FINAL(r, x, y) r
#define MUL(x, y) MUL_FINAL(WHILE(MUL_PRED, MUL_OP, 0, x, y))
EVAL(MUL(2, 3)) // Expands to 6
Division and subtraction can be built in a similiar way.
I compiled a file containing the following lines using gcc -E.
#define MUL(A, B) ((A)*(B))
#define CONST_A 10
#define CONST_B 20
int foo()
{
return MUL(CONST_A, CONST_B);
}
The output was:
# 1 "test-96.c"
# 1 "<command-line>"
# 1 "test-96.c"
int foo()
{
return ((10)*(20));
}
That's just one data point for you.
I have to generate redundant asm code which keeps calling different C functions
i am trying to do something like
#define CODE_GEN(func) push a \
call func
pop a
invoking something like
CODE_GEN(foo)
will generate
bash-4.1$ gcc -E mk.S
# 1 "mk.S"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "mk.S"
# 1 "asm_gen.h" 1
# 2 "mk.S" 2
# 13 "mk.S"
pusha call foo popa iret
but this fails in compilation
bash-4.1$ gcc -m32 mk.S
mk.S: Assembler messages:
mk.S:13: Error: junk `foo popa iret' after expression
mk.S:13: Error: suffix or operands invalid for `pusha'
is there a way to delimit asm code written in a single line in a .S file ?
semicolons ';' can be used in place of line breaks.
So something like
#define CODE_GEN(func) push a; \
call func; \
pop a;
will compile and work
Yes, by using semicolons, see the other answer. C macros expand to a single string with no line breaks, but semicolons get around that.
You can also use GNU Assembler macros. This is totally untested, could be wrong:
.macro CODEGEN func
push a
call \func
pop a
.endm
As an example of the problem, is there any way to implement the macro partialconcat in the following code?
#define apply(f, x) f(x)
apply(partialconcat(he),llo) //should produce hello
EDIT:
Here's another example, given a FOR_EACH variadic macro (see an example implementation in this answer to another question).
Say I want to call a member on several objects,
probably within another macro for a greater purpose.
I would like a macro callMember that behaves like this:
FOR_EACH(callMember(someMemberFunction), a, b, c);
produces
a.someMemberFunction(); b.someMemberFunction(); c.someMemberFunction();
This needs callMember(someMember) to produce a macro that behaves like
#define callMember_someMember(o) o.someMember()
You can achieve the desired result with the preprocessor using Vesa Karvonen's incredible "Order" language/library: http://rosettacode.org/wiki/Order
This works by implementing a whole second high-level language on top of the preprocessor itself, with support for things like currying and first-class macros and so on. It's pretty heavy-duty though, nontrivial Order code takes a very long time to compile because CPP wasn't designed to be used in that way, and most C compilers can't handle it. It's also very fragile: errors in the input code tend to produce incomprehensible gibberish output.
But yes, it can be done, and done in one preprocessor pass. It's just a lot more complicated than you might have been expecting.
Use higher order macros:
#define OBJECT_LIST(V) \
V(a) \
V(b) \
V(c)
#define MEMBER_CALL(X) \
X.some_func();
OBJECT_LIST(MEMBER_CALL)
output
$ g++ -E main.cc
# 1 "main.cc"
# 1 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 1 "<command-line>" 2
# 1 "main.cc"
# 10 "main.cc"
a.some_func(); b.some_func(); c.some_func();
since it is a compile time loop, currying is difficult. the OBJECT_LIST macro defines how many arguments every user of this list is allowed to curry. the (default) function call arguments are part of the define then. You can freely choose not to use the default supplied argument or use a constant value yourself. I was not able to find a proper way to reduce the amount of arguments in the preprocessor. This fact limits the generality of this technique.
#define OBJECT_LIST(V) \
V(a, 1,2,3) \
V(b, 4,5,6)
#define MEMBER_CALL(X, A1, A2, A3) \
X.somefunc(A1, A2, A3);
#define CURRY_CALL(X, A1, A2, A3) \
X.somefunc(A1, 2, 2);
#define NO_CURRY_CALL(X, A1, A2, A3) \
X.xomefunc(A1);
OBJECT_LIST(MEMBER_CALL)
OBJECT_LIST(CURRY_CALL)
OBJECT_LIST(NO_CURRY_CALL)
output:
# 1 "main2.cc"
# 1 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 1 "<command-line>" 2
# 1 "main2.cc"
# 12 "main2.cc"
a.somefunc(1, 2, 3); b.somefunc(4, 5, 6);
a.somefunc(1, 2, 2); b.somefunc(4, 2, 2);
a.somefunc(1); b.somefunc(4);
The C preprocessor is 'only' a simple text processor. In particular, one macro cannot define another macro; you cannot create a #define out of the expansion of a macro.
I think that means that the last two lines of your question:
This needs callMember(someMember) to produce a macro that behaves like
#define callMember_someMember(o) o.someMember()
are not achievable with a single application of the C preprocessor (and, in the general case, you'd need to apply the preprocessor an arbitrary number of times, depending on how the macros are defined).