supressing "extra ;" warnings with GCC 3.4
Hi folks, Tried to compile our code with GCC 3.4 last night; our default is to always keep the warning levels turned all the way up. I'm getting many errors of the "extra `;'" type, as the result of various preprocessor metaprogramming constructs. Specifically, if a macro expands to a function definition (silly example): #define FOO(T) \ inline T FOO(T i) { ... } FOO(int); FOO(double); The semicolons after the macro invocations give GCC 3.4 fits; but without the semicolons, it looks strange, editors can't indent, etc. Is anyone aware of a way to silence the "extra ;" errors? (I've looked through their docs, can't find anything; I suspect other Boost users have run across this.) Is there something I'm missing in the preprocessor library that handles this sort of thing? Any help appreciated! Thanks! ---------------------------------------------------------------------- Dave Steffen, Ph.D. "There are two ways to write error-free Software Engineer IV programs; only the third one works." Numerica Corporation ph (970) 419-8343 x27 "Pie are not square. Pie are round. fax (970) 223-6797 Cornbread are square" dgsteffen@numerica.us ... anon (usenet)
Dave Steffen
#define FOO(T) \
#define FOO do{/* here goes your macro */} while(0)
Is anyone aware of a way to silence the "extra ;" errors? (I've
semicolon is required after "while(0)", thus compiler will no complain any longer if you put whole macro inside "do{...} while(0)" block, as shown above. It's very old trick, actually ... B.
Bronek Kozicki writes:
Dave Steffen
wrote: #define FOO(T) \
#define FOO do{/* here goes your macro */} while(0)
Yes, I've seen this in the GCC documentation. Unfortunately, it doesn't help if you're doing the sort of preprocessor metaprogramming we're doing. In one case in particular, the end result of the macro really is supposed to be a _function declaration_, not a section of code. In another case, it shows up from the construct #define NUM_SIG_CONNECTION_FUNCTIONS_FOR_MEMBERS(first,last) \ BOOST_PP_REPEAT_FROM_TO(BOOST_PP_ADD(first,1),BOOST_PP_ADD(last,2),\ NUM_SIG_DECLARE_CONNECT,BOOST_PP_EMPTY) I don't claim to understand everything that's going on here (even remotely), but GCC 3.2 and 3.3 are very happy with the usage (in a header file) NUM_SIG_CONNECTION_FUNCTIONS_FOR_MEMBERS(0, MAX_SIGNAL_ARGS); while 3.4 complains about that semicolon. What I'm asking is A) does anyone know if 3.4 has a particular -Wno-extra-semicolon, or equivalent, to turn off that warning; or B) what is the proper preprocessor metaprogramming technique to silence the warning. Thanks!! ---------------------------------------------------------------------- Dave Steffen, Ph.D. "There are two ways to write error-free Software Engineer IV programs; only the third one works." Numerica Corporation ph (970) 419-8343 x27 "Pie are not square. Pie are round. fax (970) 223-6797 Cornbread are square" dgsteffen@numerica.us ... anon (usenet) ___________________ Numerica Disclaimer: This message and any attachments are intended only for the individual or entity to which the message is addressed. It is proprietary and may contain privileged information. If you are neither the intended recipient nor the agent responsible for delivering the message to the intended recipient, you are hereby notified that any review, retransmission, dissemination, or taking of any action in reliance upon, the information in this communication is strictly prohibited, and may be unlawful. If you feel you have received this communication in error, please notify us immediately by returning this Email to the sender and deleting it from your computer.
-----Original Message----- From: boost-users-bounces@lists.boost.org [mailto:boost-users-bounces@lists.boost.org] On Behalf Of Dave Steffen
Yes, I've seen this in the GCC documentation. Unfortunately, it doesn't help if you're doing the sort of preprocessor metaprogramming we're doing. In one case in particular, the end result of the macro really is supposed to be a _function declaration_, not a section of code.
In another case, it shows up from the construct
#define NUM_SIG_CONNECTION_FUNCTIONS_FOR_MEMBERS(first,last) \ BOOST_PP_REPEAT_FROM_TO(BOOST_PP_ADD(first,1),BOOST_PP_ADD(last,2),\ NUM_SIG_DECLARE_CONNECT,BOOST_PP_EMPTY)
I don't claim to understand everything that's going on here (even remotely), but GCC 3.2 and 3.3 are very happy with the usage (in a header file)
NUM_SIG_CONNECTION_FUNCTIONS_FOR_MEMBERS(0, MAX_SIGNAL_ARGS);
while 3.4 complains about that semicolon. What I'm asking is A) does anyone know if 3.4 has a particular -Wno-extra-semicolon, or equivalent, to turn off that warning; or B) what is the proper preprocessor metaprogramming technique to silence the warning.
The proper technique is to get rid of the semicolon. A macro invocation is not an expression, though it may expand to one, and it is not a function call. Adding the semicolon and then trying to get around the warning (which should be an error) only encourages the view that macros invocations and function calls are equivalent. Nearly all macro-related problems (other than name collision) are a result of this fundamentally flawed perspective. The use of all caps should be make it obvious that a macro is involved. Making macro invocations appear more like function calls is evil--don't do it. Regards, Paul Mensonides
Paul Mensonides writes:
-----Original Message----- From: boost-users-bounces@lists.boost.org [mailto:boost-users-bounces@lists.boost.org] On Behalf Of Dave Steffen
Yes, I've seen this in the GCC documentation. Unfortunately, it doesn't help if you're doing the sort of preprocessor metaprogramming we're doing. In one case in particular, the end result of the macro really is supposed to be a _function declaration_, not a section of code.
In another case, it shows up from the construct
#define NUM_SIG_CONNECTION_FUNCTIONS_FOR_MEMBERS(first,last) \ BOOST_PP_REPEAT_FROM_TO(BOOST_PP_ADD(first,1),BOOST_PP_ADD(last,2),\ NUM_SIG_DECLARE_CONNECT,BOOST_PP_EMPTY)
I don't claim to understand everything that's going on here (even remotely), but GCC 3.2 and 3.3 are very happy with the usage (in a header file)
NUM_SIG_CONNECTION_FUNCTIONS_FOR_MEMBERS(0, MAX_SIGNAL_ARGS);
while 3.4 complains about that semicolon. What I'm asking is A) does anyone know if 3.4 has a particular -Wno-extra-semicolon, or equivalent, to turn off that warning; or B) what is the proper preprocessor metaprogramming technique to silence the warning.
The proper technique is to get rid of the semicolon. A macro invocation is not an expression, though it may expand to one, and it is not a function call. Adding the semicolon and then trying to get around the warning (which should be an error) only encourages the view that macros invocations and function calls are equivalent. Nearly all macro-related problems (other than name collision) are a result of this fundamentally flawed perspective. The use of all caps should be make it obvious that a macro is involved. Making macro invocations appear more like function calls is evil--don't do it.
Right. These macros are _not_ trying to look like function calls. Trying to make macros act like function calls _is_ evil, and we don't do that. Much. :-) This is not the problem. These macros _are_ part of some metaprogramming constructs that are attempting to automate the declaration of a suite of fuctions; or, alterately, are the NUM_SIG_CONNECTION_FUNCTIONS_FOR_MEMBERS thing I mentioned above, which is part of our wrapper around Boost's signal library. I claim that our macros and use thereof is A) correct and B) safe. It just so happens that these macro constructs occasionally expand to something that has an extra semicolon, which triggers a warning in GCC 3.4 that we haven't seen before. What I'm asking is this: assuming that our macros and useage thereof is correct, how do we A) silence the GCC warning about extra semicolons, or B) modify the construct so that the trailing semicolon is "legal", or at least "something that won't scare the compiler". :-) ---------------------------------------------------------------------- Dave Steffen, Ph.D. "There are two ways to write error-free Software Engineer IV programs; only the third one works." Numerica Corporation ph (970) 419-8343 x27 "Pie are not square. Pie are round. fax (970) 223-6797 Cornbread are square" dgsteffen@numerica.us ... anon (usenet) ___________________ Numerica Disclaimer: This message and any attachments are intended only for the individual or entity to which the message is addressed. It is proprietary and may contain privileged information. If you are neither the intended recipient nor the agent responsible for delivering the message to the intended recipient, you are hereby notified that any review, retransmission, dissemination, or taking of any action in reliance upon, the information in this communication is strictly prohibited, and may be unlawful. If you feel you have received this communication in error, please notify us immediately by returning this Email to the sender and deleting it from your computer.
Dave Steffen
I claim that our macros and use thereof is A) correct and B) safe. It just so happens that these macro constructs occasionally expand to something that has an extra semicolon, which triggers a warning in GCC 3.4 that we haven't seen before.
The warning will be an error on other compilers. The semicolons aren't just "bad style;" they're illegal.
What I'm asking is this: assuming that our macros and useage thereof is correct,
Well, it's not correct if you expect those semicolons to be usable after them.
how do we
A) silence the GCC warning about extra semicolons, or
I wouldn't count on there being a way.
B) modify the construct so that the trailing semicolon is "legal", or at least "something that won't scare the compiler".
I suggest you use Emacs or some other programmable editor and teach its indentation mode about your macros if automatic indentation is that important. -- Dave Abrahams Boost Consulting www.boost-consulting.com
David Abrahams wrote:
Dave Steffen
writes: I claim that our macros and use thereof is A) correct and B) safe. It just so happens that these macro constructs occasionally expand to something that has an extra semicolon, which triggers a warning in GCC 3.4 that we haven't seen before.
The warning will be an error on other compilers. The semicolons aren't just "bad style;" they're illegal.
Uhh... why? Example? Paul
On Thu, 2005-06-30 at 08:30 -0400, David Abrahams wrote:
Dave Steffen
writes: I claim that our macros and use thereof is A) correct and B) safe. It just so happens that these macro constructs occasionally expand to something that has an extra semicolon, which triggers a warning in GCC 3.4 that we haven't seen before.
The warning will be an error on other compilers. The semicolons aren't just "bad style;" they're illegal.
I believe The Book specifically allows an optional semicolon at the end of a function declaration in the global scope. They are illegal in a class. And necessary at the end of a class/struct definition. I have a friend who runs into this problem a lot. :D Gen
Gen Zhang writes:
On Thu, 2005-06-30 at 08:30 -0400, David Abrahams wrote:
Dave Steffen
writes: I claim that our macros and use thereof is A) correct and B) safe. It just so happens that these macro constructs occasionally expand to something that has an extra semicolon, which triggers a warning in GCC 3.4 that we haven't seen before.
The warning will be an error on other compilers. The semicolons aren't just "bad style;" they're illegal.
I believe The Book specifically allows an optional semicolon at the end of a function declaration in the global scope. They are illegal in a class. And necessary at the end of a class/struct definition. I have a friend who runs into this problem a lot. :D
Yeah, this is one question - is it legal? If so, the next question is : can we find anything to stick on the end of these macros to make it legal? For example, I think a variable declaration might be OK there. So maybe we do something like having the macro expand into (this is nasty, but it might work) int Foo() { ... } int i_am_a_variable_at_line_970_of_file_X in which case a trailing semicolon would be perfectly at home. Of course, this is rather nasty for all kinds of reasons. Is there a way to make a "null declaration"? :-) ---------------------------------------------------------------------- Dave Steffen, Ph.D. "There are two ways to write error-free Software Engineer IV programs; only the third one works." Numerica Corporation ph (970) 419-8343 x27 "Pie are not square. Pie are round. fax (970) 223-6797 Cornbread are square" dgsteffen@numerica.us ... anon (usenet) ___________________ Numerica Disclaimer: This message and any attachments are intended only for the individual or entity to which the message is addressed. It is proprietary and may contain privileged information. If you are neither the intended recipient nor the agent responsible for delivering the message to the intended recipient, you are hereby notified that any review, retransmission, dissemination, or taking of any action in reliance upon, the information in this communication is strictly prohibited, and may be unlawful. If you feel you have received this communication in error, please notify us immediately by returning this Email to the sender and deleting it from your computer.
// Compiled (gcc 3.4.3) and run on a Red Hat system (2.4.20-8 kernel) with: // g++ -o feh feh.C && ./feh // /* Next line is sole output. feh! */ #include <iostream> int main(int argc, char **argv) { std::cerr << "feh!\n"; return 0; } ; ;
Brian Allison wrote:
The next production rule is:
/simple-declaration: decl-specifier-seqopt init-declarator-listopt ;/
Note that the only thing that isn't /optional/ is the semicolon.
Presuming the book has no typos, presuming the grammar is a valid representation of the C++ specification,
This grammar matches that given in the standard, but that is informative, not normative. It is not allowable for both the "optional" parts to be missing. 7/3 says that "...the optional /init-declarator-list /can be omitted only when declaring a class...or enumeration..." and 7/7 says that "[o]nly in function declarations for constructors, destructors, and type conversions can the /decl-specifier-seq /be omitted."
then it would seem that a spurious semicolon at the end of any global declaration is itself a global declaration and is not an error.
It is an error. A redundant semi-colon is only allowed as a degenerate case of an expression statement, where such statements are allowed, or immediately after a member function definition within a class definition. Ben.
Hi Folks, Having gotten a big delivery out the door, I can come back to the issue. First, let me thank all those who have taken the time to reply; I appreciate your time and knowledge. David Abrahams writes:
The warning will be an error on other compilers. The semicolons aren't just "bad style;" they're illegal.
and several others agreed with him. Plus or minus Brian Allison's comments on C++ grammar, it sounds like we need to get rid of them; which is to say, the correct thing to do is _not_ turn off GCC's warnings, but to believe them and fix our code. I suspected this was the case (we usually trust GCC), but wasn't sure; we are doing some 'odd' things with macros (odd to anybody who hasn't seen what Boost's preprocessor metaprogramming library is up to ;-) that might trigger a nervous compiler to emit warnings. David Abrahams continued:
I suggest you use Emacs or some other programmable editor and teach its indentation mode about your macros if automatic indentation is that important.
Most of us live on Emacs; I was hoping to get away with not mucking about with the indentation rules (Emacs tends to indent things 'the way I like them' when there are semicolons in certain places). This is, of course, an annoyance, not a fundamental issue. :-) me22 wrote:
How about adding a superfluous struct at the end of the function?
#define f(T) void my_func(T i) { do_sthg(); } struct semicolon_eater {}
I haven't tried this yet, but it's the sort of thing I was fishing for. If the language says semicolons are illegal in certain places, but I want semicolons there (maybe for good reasons, maybe "just because, dammit!"), is there a clever construct that will let me get away with it? I'm gonna go try this (or something like it) soon, will report back. The advisability of doing this sort of thing is, perhaps, debatable; one of the reasons I wanted to push to GCC 3.4 is precisely this sort of thing: what are we doing that we shouldn't be? Thanks again. ---------------------------------------------------------------------- Dave Steffen, Ph.D. "There are two ways to write error-free Software Engineer IV programs; only the third one works." Numerica Corporation ph (970) 419-8343 x27 "Pie are not square. Pie are round. fax (970) 223-6797 Cornbread are square" dgsteffen@numerica.us ... anon (usenet) ___________________ Numerica Disclaimer: This message and any attachments are intended only for the individual or entity to which the message is addressed. It is proprietary and may contain privileged information. If you are neither the intended recipient nor the agent responsible for delivering the message to the intended recipient, you are hereby notified that any review, retransmission, dissemination, or taking of any action in reliance upon, the information in this communication is strictly prohibited, and may be unlawful. If you feel you have received this communication in error, please notify us immediately by returning this Email to the sender and deleting it from your computer.
Hi Folks, Having gotten a big delivery out the door, I can come back to the issue. First, let me thank all those who have taken the time to reply; I appreciate your time and knowledge. David Abrahams writes:
The warning will be an error on other compilers. The semicolons aren't just "bad style;" they're illegal.
and several others agreed with him. Plus or minus Brian Allison's comments on C++ grammar, it sounds like we need to get rid of them; which is to say, the correct thing to do is _not_ turn off GCC's warnings, but to believe them and fix our code. I suspected this was the case (we usually trust GCC), but wasn't sure; we are doing some 'odd' things with macros (odd to anybody who hasn't seen what Boost's preprocessor metaprogramming library is up to ;-) that might trigger a nervous compiler to emit warnings. David Abrahams continued:
I suggest you use Emacs or some other programmable editor and teach its indentation mode about your macros if automatic indentation is that important.
Most of us live on Emacs; I was hoping to get away with not mucking about with the indentation rules (Emacs tends to indent things 'the way I like them' when there are semicolons in certain places). This is, of course, an annoyance, not a fundamental issue. :-) me22 wrote:
How about adding a superfluous struct at the end of the function?
#define f(T) void my_func(T i) { do_sthg(); } struct semicolon_eater {}
I haven't tried this yet, but it's the sort of thing I was fishing for. If the language says semicolons are illegal in certain places, but I want semicolons there (maybe for good reasons, maybe "just because, dammit!"), is there a clever construct that will let me get away with it? I'm gonna go try this (or something like it) soon, will report back. The advisability of doing this sort of thing is, perhaps, debatable; one of the reasons I wanted to push to GCC 3.4 is precisely this sort of thing: what are we doing that we shouldn't be? Thanks again. ---------------------------------------------------------------------- Dave Steffen, Ph.D. "There are two ways to write error-free Software Engineer IV programs; only the third one works." Numerica Corporation ph (970) 419-8343 x27 "Pie are not square. Pie are round. fax (970) 223-6797 Cornbread are square" dgsteffen@numerica.us ... anon (usenet) ___________________ Numerica Disclaimer: This message and any attachments are intended only for the individual or entity to which the message is addressed. It is proprietary and may contain privileged information. If you are neither the intended recipient nor the agent responsible for delivering the message to the intended recipient, you are hereby notified that any review, retransmission, dissemination, or taking of any action in reliance upon, the information in this communication is strictly prohibited, and may be unlawful. If you feel you have received this communication in error, please notify us immediately by returning this Email to the sender and deleting it from your computer.
-----Original Message----- From: boost-users-bounces@lists.boost.org [mailto:boost-users-bounces@lists.boost.org] On Behalf Of Dave Steffen
How about adding a superfluous struct at the end of the function?
#define f(T) void my_func(T i) { do_sthg(); } struct semicolon_eater {}
I haven't tried this yet, but it's the sort of thing I was fishing for. If the language says semicolons are illegal in certain places, but I want semicolons there (maybe for good reasons, maybe "just because, dammit!"), is there a clever construct that will let me get away with it?
I'm gonna go try this (or something like it) soon, will report back. The advisability of doing this sort of thing is, perhaps, debatable; one of the reasons I wanted to push to GCC 3.4 is precisely this sort of thing: what are we doing that we shouldn't be?
As I'm sure you're aware of my opinion on this, so I won't repeat it. If you going to do it anyway, then add a namespace somewhere... namespace empty { }; ...and then make the macro expansion end with: using namespace ::empty As in, #define f() \ void my_func() { do_something(); } \ using namespace ::empty \ /**/ f(); This shouldn't introduce any names into whatever scope you're in. Regards, Paul Mensonides
-----Original Message----- From: boost-users-bounces@lists.boost.org [mailto:boost-users-bounces@lists.boost.org] On Behalf Of Dave Steffen
Right. These macros are _not_ trying to look like function calls. Trying to make macros act like function calls _is_ evil, and we don't do that. Much. :-) This is not the problem.
Okay.
These macros _are_ part of some metaprogramming constructs that are attempting to automate the declaration of a suite of fuctions; or, alterately, are the NUM_SIG_CONNECTION_FUNCTIONS_FOR_MEMBERS thing I mentioned above, which is part of our wrapper around Boost's signal library.
I claim that our macros and use thereof is A) correct and B) safe. It just so happens that these macro constructs occasionally expand to something that has an extra semicolon, which triggers a warning in GCC 3.4 that we haven't seen before. What I'm asking is this: assuming that our macros and useage thereof is correct, how do we
A) silence the GCC warning about extra semicolons, or B) modify the construct so that the trailing semicolon is "legal", or at least "something that won't scare the compiler".
Okay, let me get this straight. Are you saying that the macro invocation is generating code that sometimes requires a closing semicolon to be applied and sometimes not, or are you saying that you just want to be able to put the semicolon there regardless? If it's the latter, then you should bite the bullet and remove the semicolon. If it is the former, than the code generator should yield the semicolon when necessary. Regards, Paul Mensonides
How about adding a superfluous struct at the end of the function? #define f(T) void my_func(T i) { do_sthg(); } struct semicolon_eater {} - me22
participants (9)
-
Ben Hutchings
-
Brian Allison
-
Bronek Kozicki
-
Dave Steffen
-
David Abrahams
-
Gen Zhang
-
me22
-
Paul Johnson
-
Paul Mensonides