How to require a semicolon after a macro
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:
-pedantic -ansi -std=c++98 -Werror
-Weverything
-Wall -Wextra
TESTSUITE(X)
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
.
-Wglobal-constructors
If I surround it with _Pragma
like this:
_Pragma
#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).
-pedantic
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).
_Pragma
So does anyone have an idea how I can require the semicolon and also have 0 warnings?
__attribute((constructor))__
@chris good to know - thanks. but I prefer the solution I already have because I also have to deal with windows compilers and having the same set of macros is better for me
– onqtam
Feb 21 '16 at 1:34
Yeah, looks complicated. If it's any consolation, Clang is available with Visual Studio now.
– chris
Feb 21 '16 at 2:47
2 Answers
2
You can add a function declaration at the end of the macro:
#define TESTSUITE(name)
//...
void ANONYMOUS_FUNCTION()
Demo
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.
TESTSUITE
thanks bro! life saver
– onqtam
Feb 21 '16 at 1:01
It looks like GCC can give better errors with
(void)0
, or possibly (void)"TESTSUITE requires a semicolon"
if the string literal ever gets shown in an error. Clang's error remains almost identical.– chris
Feb 21 '16 at 1:25
(void)0
(void)"TESTSUITE requires a semicolon"
@chris
(void)0;
is an error outside of a function– M.M
Feb 21 '16 at 3:49
(void)0;
@M.M, Good point. I wasn't thinking :p
– chris
Feb 21 '16 at 3:55
I use enum
at the end of a macro to force a semicolon.
enum
This works both inside and outside classes and functions.
This approach does not pollute any namespaces and does not generate any code.
cool - i'll try this!
– onqtam
Sep 1 at 0:20
Thanks for contributing an answer to Stack Overflow!
But avoid …
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
But avoid …
To learn more, see our tips on writing great answers.
Required, but never shown
Required, but never shown
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
To call a function on startup, you can give it the non-standard
__attribute((constructor))__
.– chris
Feb 21 '16 at 1:27