Reputation: 4538
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?
Upvotes: 17
Views: 10655
Reputation: 1345
As the last line of a macro, I use struct HereToEnforceSemiColon
, i.e.
#define MYMACRO(param) \
DoSomething(param); \
struct HereToEnforceSemiColon
Upvotes: 0
Reputation: 5615
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
Upvotes: 9
Reputation: 1513
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.
Upvotes: 27
Reputation: 1
I use enum {}
at the end of a macro to force a semicolon.
This works both inside and outside classes and functions.
This approach does not pollute any namespaces and does not generate any code.
Upvotes: 6
Reputation: 41321
You can add a function declaration at the end of the macro:
#define TESTSUITE(name) \
//... \
void ANONYMOUS_FUNCTION()
The function name doesn't even have to be different across different TESTSUITE
macros. It's sufficient if it's just not used anywhere else so it doesn't participate in any overloading.
Upvotes: 8