what is the difference between "do { free(x); x = NULL; } while (0);" and "{ free(x); x = NULL; }"

#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

Answers (4)

AnT stands with Russia
AnT stands with Russia

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

NPE
NPE

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

netcoder
netcoder

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

Ramy Al Zuhouri
Ramy Al Zuhouri

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

Related Questions