Is there a way to evaluate an expression before stringification in c?
example:
#define stringify(x) #x
...
const char * thestring = stringify( 10 * 50 );
The problem is that I want to get
const char * thestring = "500";
And not:
const char * thestring = "10 * 50";
Can this be done?
I'll take a wild guess that you have more experience in scripting languages than in C.
There are multiple phases you have to be aware of with a purely compiled language like C: Preproccesing, Compiling, Linking, and Running
First the preprocessor is run. That is where your macro gets expanded. At this point, its contents are "10 * 50". Not much to be done about that.
After the macro pre-processor completes, then the compiler converts the program into an object file
After the compiler finishes on every source file, the linker steps in and slaps them all together.
Finally, when your user is ready, they execute your program. Semanticly, this is when the 10 * 50 gets calculated. (In actuality, most compilers will recognize that this will always be the same value, and replace it with 500, but that's an implementation detail).
Scripting languages like to blur all these lines, so I can see where someone used to one of those might be confused.
The C preprocessor cannot do that, so use snprintf
instead:
char *stringify(int n) {
char *res = malloc(12);
snprintf(res, 12, "%d", n);
return res;
}
const char *thestring = stringify(10 * 50);
For simplicity's sake I've omitted error control and free
.
You probably won't like the format in which the expression is going to be presented, yes, it is possible, but in a very eclectic way - you'd need to create a separate functional language that is being "run" by the preprocessor. The proof:
$ cvs -d:pserver:[email protected]:/cvsroot/chaos-pp login
$ cvs -z3 -d:pserver:[email protected]:/cvsroot/chaos-pp co -P chaos-pp
$ cvs -z3 -d:pserver:[email protected]:/cvsroot/chaos-pp co -P order-pp
$ cd order-pp/example
$ grep -A 6 'int main' fibonacci.c
int main(void) {
printf
("The 500th Fibonacci number is "
ORDER_PP(8stringize(8to_lit(8fib(8nat(5,0,0)))))
".\n");
return 0;
}
$ cpp -I../inc fibonacci.c 2>/dev/null | grep -A 6 'int main'
int main(void) {
printf
("The 500th Fibonacci number is "
"139423224561697880139724382870407283950070256587697307264108962948325571622863290691557658876222521294125"
".\n");
return 0;
}
In this example we have newly-made preprocessor-run purely functional language being used to calculate 500th Fibonacci number and then stringize it to give to C compiler.
Of course I very much doubt that this is something that you'd ever use in practice, and it is a very far stretched abuse of the preprocessor, but I consider it to be a very thought-provoking hack. (and yes, without the exotic theoretical twists like this one, it's not possible).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With