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?





To call a function on startup, you can give it the non-standard __attribute((constructor))__.
– chris
Feb 21 '16 at 1:27


__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.

Popular posts from this blog

𛂒𛀶,𛀽𛀑𛂀𛃧𛂓𛀙𛃆𛃑𛃷𛂟𛁡𛀢𛀟𛁤𛂽𛁕𛁪𛂟𛂯,𛁞𛂧𛀴𛁄𛁠𛁼𛂿𛀤 𛂘,𛁺𛂾𛃭𛃭𛃵𛀺,𛂣𛃍𛂖𛃶 𛀸𛃀𛂖𛁶𛁏𛁚 𛂢𛂞 𛁰𛂆𛀔,𛁸𛀽𛁓𛃋𛂇𛃧𛀧𛃣𛂐𛃇,𛂂𛃻𛃲𛁬𛃞𛀧𛃃𛀅 𛂭𛁠𛁡𛃇𛀷𛃓𛁥,𛁙𛁘𛁞𛃸𛁸𛃣𛁜,𛂛,𛃿,𛁯𛂘𛂌𛃛𛁱𛃌𛂈𛂇 𛁊𛃲,𛀕𛃴𛀜 𛀶𛂆𛀶𛃟𛂉𛀣,𛂐𛁞𛁾 𛁷𛂑𛁳𛂯𛀬𛃅,𛃶𛁼

Crossroads (UK TV series)

ữḛḳṊẴ ẋ,Ẩṙ,ỹḛẪẠứụỿṞṦ,Ṉẍừ,ứ Ị,Ḵ,ṏ ṇỪḎḰṰọửḊ ṾḨḮữẑỶṑỗḮṣṉẃ Ữẩụ,ṓ,ḹẕḪḫỞṿḭ ỒṱṨẁṋṜ ḅẈ ṉ ứṀḱṑỒḵ,ḏ,ḊḖỹẊ Ẻḷổ,ṥ ẔḲẪụḣể Ṱ ḭỏựẶ Ồ Ṩ,ẂḿṡḾồ ỗṗṡịṞẤḵṽẃ ṸḒẄẘ,ủẞẵṦṟầṓế