I have following piece of code,
Scenario 1
/* get count of elements in an array */
#define COUNT(x) sizeof(x)/sizeof(x[0])
struct Data data[] = {/* some data goes here */};
int count = COUNT(data);
Scenario 2
#define TOTAL 32
#define EACH 4
int count = (TOTAL/EACH)
I know macros are resolved during preprocessing and sizeof is a compile time operator, but what about the division: does it get optimised during compilation ?
Is there any tool to see the optimizations done by the compiler ?
Usually you can let the compiler show you the generated assembly code. With Visual C++ you can do that with the /Fa<file>
option. gcc
has the -S
option.
As for your question: Most compilers should precompute constant expressions, at least at optimisation levels higher than O0
.
Let's see with your example scenarios:
#define COUNT(x) sizeof(x)/sizeof(x[0])
int data[] = {1, 2, 3, 4, 5};
int count = COUNT(data);
Compiled with cl /c /Fascenario1.asm scenario1.c
yields:
...
PUBLIC _data
PUBLIC _count
_DATA SEGMENT
_data DD 01H
DD 02H
DD 03H
DD 04H
DD 05H
_count DD 05H
_DATA ENDS
END
You see the value for count
close to the end, and it's indeed 5. So the compiler computed the value even with no optimisation turned on.
Your second scenario:
#define TOTAL 32
#define EACH 4
int count = (TOTAL/EACH);
yields
...
PUBLIC _count
_DATA SEGMENT
_count DD 08H
_DATA ENDS
END
where the expression was precomputed as well.
It's not uncommon at higher optimisation levels for the compiler to even evalute more complex expressions when you pass compile-time constants. As an example, I once looked at the code of three different ways of swapping two integers and once I turned optimisation on the compiler simply threw out the call to the swap method entirely, replacing the arguments to my test printf
with the already-swapped values.