The whole idea behind this trick is to find a way to create a multi-line (i.e compound) statement that also incorporates a terminating ; as its integral part. That will give you the opportunity to use ; after your macro invocation without inadvertently introducing an empty statement.
The ordinary compound statement in { ... } doesn't work because it does not end in ;. The only multi-line statement in C/C++ that ends in ; is do/while. There's no other statements in C/C++ grammar that would satisfy this requirement. (This is an inaccurate claim, see my "P.S." below)
In all other cases (including your if (1) {...}) the ; after the macro invocation will be seen as an additional independent standalone empty statement. This will make it impossible to write a ; after your macro invocation when it is used in contexts requiring exactly one statement (like true branch of if-else or the body of do/while cycle).
For example, if you define
#define A() if (1) {}
then this code will not compile
do
A();
while (1);
because it will be replaced with
do
if (1) {}; /* <- two statements, not one */
while (1);
and that is actually two statements between do and while. Specifying two statements between do and while without wrapping them into {} is syntax error.
P.S. Correction: The claim I make above about do/while being the only viable variant is incorrect . In @Michael Burr's answer you can see another suitable variant, which is using the else ((void) 0) trick for the same purpose. However, the main principle remains the same.