Can the C preprocessor perform arithmetic and if so, how? - c

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.

Related

Is math within macro computed at compile time?

For example, does MIN_N_THINGIES below compile to 2? Or will I recompute the division every time I use the macro in code (e.g. recomputing the end condition of a for loop each iteration).
#define MAX_N_THINGIES (10)
#define MIN_N_THINGIES ((MAX_N_THINGIES) / 5)
uint8_t i;
for (i = 0; i < MIN_N_THINGIES; i++) {
printf("hi");
}
This question stems from the fact that I'm still learning about the build process. Thanks!
If you pass -E to gcc it will show what the preprocessor stage outputted.
gcc -E test.c | tail -n11
Outputs:
# 3 "test.c" 2
int main() {
uint8_t i;
for (i = 0; i < ((10) / 5); i++) {
printf("hi");
}
return 0;
}
Then if you pass -s flag to gcc you will see that the division was optimized out. If you also pass the -o flag you can set the output files and diff them to see that they generated the same code.
gcc -S test.c -o test-with-div.s
edit test.c to make MIN_N_THINGIES equal a const 2
gcc -S test.c -o test-constant.s
diff test-with-div.s test-constant.s
// for educational purposes you should look at the .s files generated.
Then as mentioned in another comment you can change the optimization flag by using -O...
gcc -S test.c -O2 -o test-unroll-loop.s
Will unroll the for loop even such that there isn't even a loop.
Preprocessor will replace MIN_N_THINGIES with ((10)/5), then it is up to the compiler to optimize ( or not ) the expression.
Maybe. The standard does not mandate that it is or it is not. On most compilers it will do after passing optimization flags (for example gcc with -O0 does not do it while with -O2 it even unrolls the loop).
Modern compilers perform even much more complicated techniques (vectorization, loop skewing, blocking ...). However unless you really care about performance, for ex. you program HPC, program real time system etc., you probably should not care about the output of the compiler - unless you're just interested (and yes - compilers can be a fascinating subject).
No. The preprocessor does not calculate macros, they're handled by the compiler. The preprocessor can calculate arithmetic expressions (no floating point values) in #if conditionals though.
Macros are simply text substitutions.
Note that the expanded macros can still be calculated and optimized by the compiler, it's just that it's not done by the preprocessor.
The standard mandates that some expressions are evaluated at compile time. But note that the preprocessor does just text splicing (well, almost) when the macro is called, so if you do:
#define A(x) ((x) / (S))
#define S 5
A(10) /* Gives ((10) / (5)) == 2 */
#undef S
#define S 2
A(20) /* Gives ((20) / (2)) == 10 */
The parenteses are to avoid idiocies like:
#define square(x) x * x
square(a + b) /* Gets you a + b * a + b, not the expected square */
After preprocessing, the result is passed to the compiler proper, which does (most of) the computation in the source that the standard requests. Most compilers will do a lot of constant folding, i.e., computing (sub)expressions made of known constants, as this is simple to do.
To see the expansions, it is useful to write a *.c file of a few lines, just with the macros to check, and run it just through the preprocessor (typically someting like cc -E file.c) and check the output.

C: const initializer and debugging symbols

In code reviews I ask for option (1) below to be used as it results in a symbol being created (for debugging) whereas (2) and (3) do not appear to do so at least for gcc and icc. However (1) is not a true const and cannot be used on all compilers as an array size. Is there a better option that includes debug symbols and is truly const for C?
Symbols:
gcc f.c -ggdb3 -g ; nm -a a.out | grep _sym
0000000100000f3c s _symA
0000000100000f3c - 04 0000 STSYM _symA
Code:
static const int symA = 1; // 1
#define symB 2 // 2
enum { symC = 3 }; // 3
GDB output:
(gdb) p symA
$1 = 1
(gdb) p symB
No symbol "symB" in current context.
(gdb) p symC
No symbol "symC" in current context.
And for completeness, the source:
#include <stdio.h>
static const int symA = 1;
#define symB 2
enum { symC = 3 };
int main (int argc, char *argv[])
{
printf("symA %d symB %d symC %d\n", symA, symB, symC);
return (0);
}
The -ggdb3 option should be giving you macro debugging information. But this is a different kind of debugging information (it has to be different - it tells the debugger how to expand the macro, possibly including arguments and the # and ## operators) so you can't see it with nm.
If your goal is to have something that shows up in nm, then I guess you can't use a macro. But that's a silly goal; you should want to have something that actually works in a debugger, right? Try print symC in gdb and see if it works.
Since macros can be redefined, gdb requires the program to be stopped at a location where the macro existed so it can find the correct definition. In this program:
#include <stdio.h>
int main(void)
{
#define X 1
printf("%d\n", X);
#undef X
printf("---\n");
#define X 2
printf("%d\n", X);
}
If you break on the first printf and print X you'll get the 1; next to the second printf and gdb will tell you that there is no X; next again and it will show the 2.
Also the gdb command info macro foo can be useful, if foo is a macro that takes arguments and you want to see its definition rather than expand it with a specific set of arguments. And if a macro expands to something that's not an expression, gdb can't print it so info macro is the only thing you can do with it.
For better inspection of the raw debugging information, try objdump -W instead of nm.
However (1) is not a true const and cannot be used on all compilers as an array size.
This can be used as array size on all compilers that support C99 and latter (gcc, clang). For others (like MSVC) you have only the last two options.
Using option 3 is preferred 2. enums are different from #define constants. You can use them for debugging. You can use enum constants as l-value as well unlike #define constants.

Way to print out compile-time -calculated constants

I'm doing some microcontroller programming and I have code along these lines:
#define F_CPU 8000000
#define F_ADC (F_CPU / 64.0)
#define T_ADC (1.0/F_ADC)
Is there a way to print out the calculated values of, say T_ADC at compile time? I tried stringifying it
#define STRINGIFY(s) XSTRINGIFY(s)
#define XSTRINGIFY(s) #s
#pragma message ("T_ADC " STRINGIFY(T_ADC))
But that just gives the macro-expansion "(1/(8000000/64))", not the actual value.
This being a micro-controller program, it's awkward to do a printf at startup time. I'm using gcc and I'm happy to use any non-standard gcc features if that helps.
As #mbratch and #freddie said, the computation is made by the compiler, so you can not get the result simply using preprocessor directives.
The easiest way that comes to mind right now, is to assign the macro to a global const, and then read the value of the const using a debugger, or opening the binary image of the executable (you can get the address of the constant from the memory map file).
const float temp = T_ADC;
Note that you are forced to specify the C type, and this is an essential step since the result of the macro depends on it.
I implemented a baud rate calculation in the preprocessor for a microcontroller but tweaked the integer divide so it rounded (as truncation has more error). Then I displayed the achieved error in a series of categories of low, med and too much, but I stopped short of +-X.X% * due to the extra tedious coding effort.
It was along the lines of http://99-bottles-of-beer.net/language-c-c++-preprocessor-115.html but:-
tedious to do, as it's proportional to:-
the number of digits/categories required
the number of variables as nothing can be shared
fairly preprocessor specific
devoid of any compiler checks
As I don't have the code, the exercise/tediousness is left to the reader...
* Using scaled integer based calculations
It's not exactly what you're looking for but it'll help.
/* definition to expand macro then apply to pragma message */
#define VALUE_TO_STRING(x) #x
#define VALUE(x) VALUE_TO_STRING(x)
#define VAR_NAME_VALUE(var) #var "=" VALUE(var)
#define F_CPU 8000000
#define F_ADC (F_CPU / 64.0)
#define T_ADC (1.0/F_ADC)
#pragma message VAR_NAME_VALUE(T_ADC) /* prints note: #pragma message: T_ADC=(1.0/(8000000 / 64.0) */
This is called Stringification.
Edit: The pre-processor only does string replacement. You could use the pragma message and then use a simple script to do the computation. Continued from my comment above.
$ gcc a.c 2> out
$ python -c "print `cat out | cut -d = -f2`"
8e-06

Is partial macro application / currying possible in the C preprocessor?

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).

Can I compute pow(10,x) at compile-time in c?

Is it possible to compute pow(10,x) at compile time?
I've got a processor without floating point support and slow integer division. I'm trying to perform as many calculations as possible at compile time. I can dramatically speed up one particular function if I pass both x and C/pow(10,x) as arguments (x and C are always constant integers, but they are different constants for each call). I'm wondering if I can make these function calls less error prone by introducing a macro which does the 1/pow(10,x) automatically, instead of forcing the programmer to calculate it?
Is there a pre-processor trick? Can I force the compiler optimize out the library call?
There are very few values possible before you overflow int (or even long). For clarities sake, make it a table!
edit: If you are using floats (looks like you are), then no it's not going to be possible to call the pow() function at compile time without actually writing code that runs in the make process and outputs the values to a file (such as a header file) which is then compiled.
GCC will do this at a sufficiently high optimization level (-O1 does it for me). For example:
#include <math.h>
int test() {
double x = pow(10, 4);
return (int)x;
}
Compiles at -O1 -m32 to:
.file "test.c"
.text
.globl test
.type test, #function
test:
pushl %ebp
movl %esp, %ebp
movl $10000, %eax
popl %ebp
ret
.size test, .-test
.ident "GCC: (Ubuntu 4.3.3-5ubuntu4) 4.3.3"
.section .note.GNU-stack,"",#progbits
This works without the cast as well - of course, you do get a floating-point load instruction in there, as the Linux ABI passes floating point return values in FPU registers.
You can do it with Boost.Preprocessor:
http://www.boost.org/doc/libs/1_39_0/libs/preprocessor/doc/index.html
Code:
#include <boost/preprocessor/repeat.hpp>
#define _TIMES_10(z, n, data) * 10
#define POW_10(n) (1 BOOST_PP_REPEAT(n, _TIMES_10, _))
int test[4] = {POW_10(0), POW_10(1), POW_10(2), POW_10(3)};
Actually, by exploiting the C preprocessor, you can get it to compute C pow(10, x) for any real C and integral x. Observe that, as #quinmars noted, C allows you to use scientific syntax to express numerical constants:
#define myexp 1.602E-19 // == 1.602 * pow(10, -19)
to be used for constants. With this in mind, and a bit of cleverness, we can construct a preprocessor macro that takes C and x and combine them into an exponentiation token:
#define EXP2(a, b) a ## b
#define EXP(a, b) EXP2(a ## e,b)
#define CONSTPOW(C,x) EXP(C, x)
This can now be used as a constant numerical value:
const int myint = CONSTPOW(3, 4); // == 30000
const double myfloat = CONSTPOW(M_PI, -2); // == 0.03141592653
You can use the scientific notation for floating point values which is part of the C language. It looks like that:
e = 1.602E-19 // == 1.602 * pow(10, -19)
The number before the E ( the E maybe capital or small 1.602e-19) is the fraction part where as the (signed) digit sequence after the E is the exponent part. By default the number is of the type double, but you can attach a floating point suffix (f, F, l or L) if you need a float or a long double.
I would not recommend to pack this semantic into a macro:
It will not work for variables, floating point values, etc.
The scientific notation is more readable.
Actually, you have M4 which is a pre-processor way more powerful than the GCC’s. A main difference between those two is GCC’s is not recursive whereas M4 is. It makes possible things like doing arithmetic at compile-time (and much more!). The below code sample is what you would like to do, isn’t it? I made it bulky in a one-file source; but I usually put M4's macro definitions in separate files and tune my Makefile rules. This way, your code is kept from ugly intrusive M4 definitions into the C source code I've done here.
$ cat foo.c
define(M4_POW_AUX, `ifelse($2, 1, $1, `eval($1 * M4_POW_AUX($1, decr($2)))')')dnl
define(M4_POW, `ifelse($2, 0, 1, `M4_POW_AUX($1, $2)')')dnl
#include <stdio.h>
int main(void)
{
printf("2^0 = %d\n", M4_POW(2, 0));
printf("2^1 = %d\n", M4_POW(2, 1));
printf("2^4 = %d\n", M4_POW(2, 4));
return 0;
}
The command line to compile this code sample uses the ability of GCC and M4 to read from the standard input.
$ cat foo.c | m4 - | gcc -x c -o m4_pow -
$ ./m4_pow
2^0 = 1
2^1 = 2
2^4 = 16
Hope this help!
If you just need to use the value at compile time, use the scientific notation like 1e2 for pow(10, 2)
If you want to populate the values at compile time and then use them later at runtime then simply use a lookup table because there are only 23 different powers of 10 that are exactly representable in double precision
double POW10[] = {1., 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, 1e10,
1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, 1e20, 1e21, 1e22};
You can get larger powers of 10 at runtime from the above lookup table to quickly get the result without needing to multiply by 10 again and again, but the result is just a value close to a power of 10 like when you use 10eX with X > 22
double pow10(int x)
{
if (x > 22)
return POW10[22] * pow10(x - 22);
else if (x >= 0)
return POW10[x];
else
return 1/pow10(-x);
}
If negative exponents is not needed then the final branch can be removed.
You can also reduce the lookup table size further if memory is a constraint. For example by storing only even powers of 10 and multiply by 10 when the exponent is odd, the table size is now only a half.
Recent versions of GCC ( around 4.3 ) added the ability to use GMP and MPFR to do some compile-time optimizations by evaluating more complex functions that are constant. That approach leaves your code simple and portable, and trust the compiler to do the heavy lifting.
Of course, there are limits to what it can do. Here's a link to the description in the changelog, which includes a list of functions that are supported by this. 'pow' is one them.
Unfortunately, you can't use the preprocessor to precalculate library calls. If x is integral you could write your own function, but if it's a floating-point type I don't see any good way to do this.
bdonlan's replay is spot on but keep in mind that you can perform nearly any optimization you chose on the compile box provided you are willing to parse and analyze the code in your own custom preprocessor. It is a trivial task in most version of unix to override the implicit rules that call the compiler to call a custom step of your own before it hits the compiler.

Resources