Yes, this is indeed a (preprocessor) macro. The way macros work in C is that they are literally string substitutions placed into the code and compiled after. It's... not ideal. They're hard to debug, not type safe, and mess up line numbers in compiler errors. So, this macro, which takes no arguments (due to:
()
), will put, literally,
{ ; }
wherever you call that macro. That code does nothing. It's not even a no-op, it will not actually add assembly code to the binary. Take this example:
C:
#include <stdio.h>
#define IDLE_WORK() { ; }
void main(){
printf("start\n");
IDLE_WORK();
printf("end\n");
}
and this code that it is assembled into:
Code:
main:
.LFB0:
.file 1 "noop_test.c"
.loc 1 6 12
.cfi_startproc
pushq %rbp #
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp #,
.cfi_def_cfa_register 6
# noop_test.c:7: printf("start\n");
.loc 1 7 2
movl $.LC0, %edi #,
call puts #
# noop_test.c:9: printf("end\n");
.loc 1 9 2
movl $.LC1, %edi #,
call puts #
# noop_test.c:10: }
.loc 1 10 1
nop
popq %rbp #
.cfi_def_cfa 7, 8
ret
.cfi_endproc
The two sections below each of the
printf
s are the same and there are no extra instructions generated between them for the macro.
Macros are commonly used to define constants. That's a pretty decent way to use them, though that's not terribly type safe. Sometimes, it's used for an arbitrary amount of code. In this case, the most idiomatic way to write a macro is thus:
C:
#define MY_AWESOME_BLOCK() do { /* CODE HERE */ } while(0)
The reason for this is that it can be used in a place that expects a single expression OR a block AND it requires a trailing semi-colon, which makes it act like a normal expression (and could one day be replaced by a non-macro function call later without changing any calling code). Take, for example:
C:
if (1 == 0){
printf("physics exploded\n");
} else MY_AWESOME_BLOCK();
If you had multiple lines in a macro but didn't wrap it in a block like the above, only the first line would be part of the
else
block and the rest would be one level up, which is most certainly not the intent. Macros are messy. Tread carefully.