Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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!

like image 393
tarabyte Avatar asked Apr 11 '14 17:04

tarabyte


People also ask

Can we define a macro at compile time?

You can define any macro on the compiler command line with -D. Use that to specify the model or variant you want, and based on that, #ifdefs in the code enable the other relevant macros.

How do you calculate compile time?

Hence taking the difference of starts and ends will give you execution time of test_case() in second multiplied by CLOCKS_PER_SEC . CLOCKS_PER_SEC is the number of clock ticks per second. Compile time calculation can be done using template metaprogramming.

Does C preprocessor do math?

The preprocessor does not do math. The results of preprocessor arithmetic can be used, for conditional preprocessor directives, inside the current preprocessor phase, but substitutions resulting from #defined expressions that are passed to the compiler are text (the replacement list).


2 Answers

Preprocessor will replace MIN_N_THINGIES with ((10)/5), then it is up to the compiler to optimize ( or not ) the expression.

like image 150
this Avatar answered Oct 02 '22 14:10

this


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.

like image 41
Eld Avatar answered Oct 02 '22 13:10

Eld