Reputation: 4904
#define FREE1(x) do { free(x); x = NULL; } while (0);
#define FREE2(x) { free(x); x = NULL; }
What is the difference between these macros?
Upvotes: 3
Views: 737
Reputation: 320747
If your question is about the do/while
trick in macros, there's no difference, because you apparently made an error in the first macro definition, which completely defeated the purpose of the trick. You put the ;
after the whole (0)
. The proper implementation should absolutely not have the ;
after the while (0)
in the first macro. This is the whole point of the do/while
trick.
Now this code will not compile
if (condition)
FREE2(arg);
else
/* something else */;
This code will not compile either
do
FREE2(arg);
while (condition);
The point of the do/while
technique is to make this code compile. But it will not compile with your FREE1
macro either because of the aforementioned error.
However, if you define the first macro correctly
#define FREE1(x) do { free(x); x = NULL; } while (0)
// No `;` at the end!!!
then the first macro will work perfectly fine in the above code samples. This is actually the reason people use the do/while
technique in multi-statement macros - to make it work correctly and uniformly with ordinary functions in such contexts.
P.S. As a side note, the purpose of all such techniques is to turn a group of multiple statements into one compound statement. In your specific case the free(x); x = NULL;
sequence can be re-implemented as a single expression (free(x), x = NULL)
, which eliminates the need for any multi-statement macro techniques, i.e. this
#define FREE3(x) (free(x), x = NULL)
will work as well. But it is a matter of personal preference.
Upvotes: 12
Reputation: 500893
Both are half-baked attempts to fix the semicolon issue discussed in Do-While and if-else statements in C/C++ macros.
A better way to define this macro is
#define FREE3(x) do { free(x); x = NULL; } while (0)
(without the trailing semicolon.)
Upvotes: 2
Reputation: 67745
Actually, there's no difference, C-wise.
The reason is you included a trailing semi-colon in:
#define FREE1(x) do { free(x); x = NULL; } while (0);
The reason you usually want to use do...while(0)
is described here, is that you generally want to use it in if...else
blocks:
if (...)
FREE(x);
else
...
But with the above usage and macros this:
if (...)
do { free(x); x = NULL; } while (0);;
else
...
...and...
if (...)
{ free(x); x = NULL; };
else
...
...are both ill-formed.
Upvotes: 5
Reputation: 22006
This:
#define FREE1(x) do { free(x); x = NULL; } while (0);
Gets executed just once, so it's the same as:
#define FREE2(x) { free(x); x = NULL; }
But in the assembly code there is a more branch.Even if a modern compiler would probably optimize it, so with all the probabilities even the assembly code generated will be the same.
Upvotes: 0