"Static const" vs "#define" for efficiency in C
c, c-preprocessor, constants, performance
Solution
Consider the following 2 test files
Test1.c: Uses static const foo.
// Test1.c uses static const..
#include <stdio.h>
static const foo = 6;
int main() {
printf("%d", foo);
return 0;
}
Test2.c: uses macro.
// Test2.c uses macro..
#include <stdio.h>
#define foo 6
int main() {
printf("%d", foo);
return 0;
}
and the corresponding assembly equivalences when using `gcc -O0`(default) are follows,
Assembly for Test1.c:
0000000000000000 <main>:
0: 55 push rbp
1: 48 89 e5 mov rbp,rsp
4: 48 83 ec 20 sub rsp,0x20
8: e8 00 00 00 00 call d <main+0xd>
d: b8 06 00 00 00 mov eax,0x6
12: 89 c2 mov edx,eax
14: 48 8d 0d 04 00 00 00 lea rcx,[rip+0x4] # 1f <main+0x1f>
1b: e8 00 00 00 00 call 20 <main+0x20>
20: b8 00 00 00 00 mov eax,0x0
25: 48 83 c4 20 add rsp,0x20
29: 5d pop rbp
2a: c3 ret
2b: 90 nop
Assembly for Test2.c:
0000000000000000 <main>:
0: 55 push rbp
1: 48 89 e5 mov rbp,rsp
4: 48 83 ec 20 sub rsp,0x20
8: e8 00 00 00 00 call d <main+0xd>
d: ba 06 00 00 00 mov edx,0x6
12: 48 8d 0d 00 00 00 00 lea rcx,[rip+0x0] # 19 <main+0x19>
19: e8 00 00 00 00 call 1e <main+0x1e>
1e: b8 00 00 00 00 mov eax,0x0
23: 48 83 c4 20 add rsp,0x20
27: 5d pop rbp
28: c3 ret
29: 90 nop
In both the cases, it is not using external memory. But the difference is that, `#define` replaces `foo` by the value, `static const` is an instruction so it increments the instruction pointer to the next instruction and it uses 1 additional register to store the value.
By this, we can say that macro is better than static constants but the difference is minimum.
EDIT: When using `-O3` compilation option (i.e at optimization on) both the test1.c and test2.c evaluates the same.
0000000000000000 <main>:
0: 48 83 ec 28 sub rsp,0x28
4: e8 00 00 00 00 call 9 <main+0x9>
9: 48 8d 0d 00 00 00 00 lea rcx,[rip+0x0] # 10 <main+0x10>
10: ba 06 00 00 00 mov edx,0x6
15: e8 00 00 00 00 call 1a <main+0x1a>
1a: 31 c0 xor eax,eax
1c: 48 83 c4 28 add rsp,0x28
20: c3 ret
21: 90 nop
So, `gcc` treats both `static const` and `#define` as the same when it optimize.
Problem
I was recently wondering what the difference between `#define` and `static const` is in C and why two methods exist to do the same things. I found some people that had similar questions here: Advantage and disadvantages of #define vs. constants? "static const" vs "#define" vs "enum" static const vs #define Lots of people talk about best practice and convention as well as give practical reasons for using one over the other, such as the need to pass a pointer to a constant, which I can do with a `static const` but not with a `#define`. However I have yet to find anyone talk about a comparison of the efficiency of the two. From what I understand about the C preprocessor, if I have a statement like this: ``` #define CONSTANT 6 ``` I create a constant value that can be used like this `char[CONSTANT]` which will actually be replaced with this statement `char[6]` prior to actually being compiled. This to me seems like it would be more efficient than using a `static const constant = 6;` because this would create a variable called constant that would live on the stack which I assume would come with some more baggage than a `#define`. Assuming I need a constant in a situation where I could choose to use either a preprocessor `#define` or a `static const` statement with no obvious reasons to choose one over the other, which is more efficient? And how exactly would I go about testing this myself?