Suppose that I have a requirement that if an operation is performed within a scope, then it must be undone in the same scope. An example of that is entering and leaving a critical section.
In order to enforce users to use paired do - undo operations, a pair of macros is defined that use open and close braces:
#define BEGIN \
{ \
do_something();
#define END \
undo_something(); \
}
Of course, there are ways that a "malicious" coder can trick those macros (e.g. by adding a an opening or closing brace), but generally this helps remembering that a BEGIN
must be followed by an END
. Moreover, if, for example, an existing BEGIN
is commented out, the compiler will complain, indicating that the END
must be removed also.
I have seen this is several internal projects. As I said, it does not offer 100% protection but could this practice prove harmful in any way? Is this a well-known practice?
If I understand the question you want to enforce the use of BEGIN
/ END
.
You can do that using the infamous goto
:
#define BEGIN \
do { \
goto check_label_end; \
label_begin: \
puts("begin"); \
} while (0);
#define END \
do { \
puts("end"); \
break; \
check_label_end: \
goto label_begin; \
} while (0);
Then, if BEGIN
is used without the END
part you receive an error:
error: label ‘check_label_end’ used but not defined
EDIT:
As pointed out by @ KlasLindbäck in comments, this version limits the use of BEGIN
/ END
to once per function.
You can pass a label name in order to use several blocks:
#define BEGIN(op) \
do { \
goto check_label_end_##op; \
label_begin_##op: \
puts("begin"); \
} while (0);
#define END(op) \
do { \
puts("end"); \
break; \
check_label_end_##op: \
goto label_begin_##op; \
} while (0);
BEGIN(undo)
...
END(undo)
BEGIN(something_else)
...
END(something_else)
For simple cases I don't see a problem, but you can construct scenarious, where this breaks your code:
BEGIN
...
for(...) {
END
...
BEGIN
}
...
END
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