Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to require a semicolon after a macro

So I am writing a library that has to build with -pedantic -ansi -std=c++98 -Werror and -Weverything for clang and -Wall -Wextra for gcc and I have this macro TESTSUITE(X) which is intended to be used in global scope like this:

TESTSUITE(current testsuite);

and what it does is call a function (on program startup by initializing a dummy var) with the string:

#define TESTSUITE(name) \
static int ANONYMOUS_VARIABLE(SOME_PREFIX) = setTestSuiteName(#name)

The problem is that this generates a warning under clang for -Wglobal-constructors.

If I surround it with _Pragma like this:

#define TESTSUITE(name)                                              \
_Pragma("clang diagnostic push");                                    \
_Pragma("clang diagnostic ignored \"-Wglobal-constructors\"");       \
static int ANONYMOUS_VARIABLE(SOME_PREFIX) = setTestSuiteName(#name) \
_Pragma("clang diagnostic pop")

the semicolon after using the macro will not be required for compilation (and when it is missing -pedantic gives an error).

If I add this at the end of the macro

static int ANONYMOUS_VARIABLE(SOME_PREFIX) = 5

the semicolon will be required but I will get a warning for an unused variable which I cannot silence (because if I surround it with _Pragma statements I will be back to square 1 not requiring a semicolon).

So does anyone have an idea how I can require the semicolon and also have 0 warnings?

like image 854
onqtam Avatar asked Feb 21 '16 00:02

onqtam


2 Answers

A bit late to the party, but I thought I'd chime in for people looking for an answer later. The recommended way to achieve this is to just wrap the macro inside a do {....} while (0). This only gets executed once and the compiler will often optimize this away for you, generating no extra code but still achieving the abstraction.

Source: https://gcc.gnu.org/onlinedocs/cpp/Swallowing-the-Semicolon.html

like image 162
Chase Avatar answered Nov 14 '22 11:11

Chase


Similar to @thomas-eding 's solution, you can put static_assert(true, "") at the end of a macro to require a semicolon.

This works both inside and outside classes and functions.

And it does not pollute any namespaces and does not generate any code.

like image 31
zwhconst Avatar answered Nov 14 '22 11:11

zwhconst