0

In the GHS compiler, if you have multiple semicolons in a row without any intervening statements, this generates a diagnostic message (warning). For example:

void myfunc()
{
}; // warning #381-D: extra ';' ignored.

This doesn't seem like a very common situation, but this warning is also issued after preprocessing has occurred, such that, the following would also generate the warning (when compiled in release):

#if _DEBUG
  #define DEBUG_VAR(x) x
#else
  #define DEBUG_VAR(x) 
#endif

void myfunc()
{
}
// global variable, used only in debug
DEBUG_VAR(int x); // warning #381-D: extra ';' ignored.

I realize that there are easy ways to workaround this in this case, it is just an illustrative example. There are many other situations with the preprocessor where you might end up with a similar construct.

Obviously, the code is legal c++, and I have never encountered such a warning message on any other compiler I have used. Is there some reasonable explanation of why this warning would be helpful, for example, is there a specific case where this warning might indicate a programming error?

MuertoExcobito
  • 9,741
  • 2
  • 37
  • 78
  • 1
    [GCC's always done it as far as I can remember](http://coliru.stacked-crooked.com/a/268f2f80a56b38e2). Perhaps you have been underspecifying warning switches this whole time? :) – Lightness Races in Orbit May 19 '15 at 13:54
  • @LightnessRacesinOrbit maybe I'm just not using -pendantic when I compile with gcc. I don't specify this to the GHS, and it gives the warning normally. – MuertoExcobito May 19 '15 at 14:00
  • 1
    "Obviously, the code is legal c++" - That's neither obvious nor true. Before C++11, which added the "empty-declaration" production, a stray semicolon outside of functions was in fact technically illegal, even though all compilers I've ever heard of accepted it as an extension. – Sebastian Redl May 19 '15 at 14:17
  • @SebastianRedl - Looking at the C++03 spec - it seems to say that empty statements are legal: 6.2 Expression statement 1 Expression statements have the form expression-statement: expressionopt ; The expression is evaluated and its value is discarded. The lvalue-to-rvalue (4.1), array-to-pointer (4.2), and function-to-pointer (4.3) standard conversions are not applied to the expression. All side effects from an expression statement are completed before the next statement is executed. An expression statement with the expression missing is called a null statement. – MuertoExcobito May 19 '15 at 14:39
  • 1
    @MuertoExcobito Statements != declarations. Statements appear in function bodies, so there stray semicolons are legal. On the file (or namespace or class) level, the compiler looks for declarations only. – Sebastian Redl May 19 '15 at 14:41
  • @sebastian redl - my mistake. So, it seems that all this warning could be warning about is a potentially missing declaration? – MuertoExcobito May 19 '15 at 22:49

2 Answers2

1

My favourite example is the "persistent semicoloner". We had one at my last place of employment. More than twice he wrote:

for (i=0; i<MAX; ++i);
    a[i] = 0;

...and was then stymied that his array wasn't initialised. And worse, he had a bug where a random variable was corrupted.

If you can't spot it, wouldn't it be nice if the compiler did?

Having said all of that, I'll agree that often a stray semicolon is "tame" - but the logic that makes a compiler spit out the error in one place doesn't discriminate in others...

John Burger
  • 3,662
  • 1
  • 13
  • 23
  • This code example wouldn't throw the warning, since the semicolon actually does something in this case. – MuertoExcobito Sep 12 '16 at 12:56
  • @MuertoExcobito Agreed. Although this example is patently incorrect, it is purely legal C, and it would take a static analsis program to highlight the out-of-bounds access - a compiler would have to assume it was deliberate. My point was more to highlight that people throw in stray semicolons that the compiler should warn against if at all possible. He definitely did far more egregious errors than the above, but I just can't think of a good example. This one took three minutes for me to find _each time_, after he'd spent three hours looking. – John Burger Sep 13 '16 at 09:33
  • Well, it does sound like a PITA... but, this isn't really an answer to my question. It would be nice if -Wempty-body worked on for-loops (for your case), but alas. – MuertoExcobito Sep 13 '16 at 12:54
-2

Is there some reasonable explanation of why this warning would be helpful, for example, is there a specific case where this warning might indicate a programming error?

Most cases, surely?

Since the ; has no meaning, either you wrote it as a redundancy (and then you have to ask "why?") or — and this is the key — you wrote it by accidentally deleting some code before it, or by getting something else wrong that confused the parser and made the ; look like it were redundant when, in fact, it weren't.

Off the top of my head, though, I can't think of an example.

But that macro would be better written like so:

#include <type_traits>
#ifndef NDEBUG
   #define DEBUG_VAR(T, N) std::common_type<T>::type N;
#else
   #define DEBUG_VAR(T, N)
#endif

void myfunc()
{}

// global variable, used only in debug
DEBUG_VAR(int, x)
Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
  • I agree, the semicolon is useless, but as my example demonstrates, there is a very common example using preprocessing macros in which you'd end up with such a pattern in your code. The code preprocessed in another configuration might not have the extra semicolon, which seems like it's probably a way more common reason to have extra semicolons. – MuertoExcobito May 19 '15 at 14:07
  • @MuertoExcobito: I don't consider that to be "common", and I would instruct e.g. interns, junior devs not to do it. The semicolon shouldn't be there, end of story. The part of my answer discussing redundancies addresses that usage. – Lightness Races in Orbit May 19 '15 at 14:08
  • This code sample is simplified from my codebase, but was based on a real situation in which I got this warning. The semicolon is not required if `_DEBUG` is not defined, ie, you are compiling in release, and will give this warning. – MuertoExcobito May 19 '15 at 14:12
  • @MuertoExcobito: It should not be there. Your macro is bad. – Lightness Races in Orbit May 19 '15 at 14:14
  • And wrt to your modified version of the code, as I said in the question, I realize there are very easy ways to work around the issue, the question is, what pitfall is this warning trying to save me from? The updated example and mine operate exactly the same. – MuertoExcobito May 19 '15 at 14:15
  • If my macro is 'bad', then maybe it should generate a warning :) – MuertoExcobito May 19 '15 at 14:15
  • I explained (admittedly, briefly) the pitfall in the answer. This edge case (a bad macro) is not a good reason to drop the benefits of the warning. – Lightness Races in Orbit May 19 '15 at 14:15
  • 2
    @LightnessRacesinOrbit I very much disagree with you. Just because there's a macro doesn't mean we should abandon common C++ syntax, and common C++ syntax is to end declarations that don't have braces (and even some that do) with a semicolon. Therefore, `DEBUG_VAR(int, x);` is better than `DEBUG_VAR(int, x)`. Primitive code editors will agree and do weird things to auto-indentation in the second case. The correct way to fix this is to define the macro to something harmless in the release case, e.g. `static_assert(true, "")` in C++11. – Sebastian Redl May 19 '15 at 14:45
  • @SebastianRedl: `DEBUG_VAR(int, x)` is not a declaration. – Lightness Races in Orbit May 19 '15 at 14:54
  • @LightnessRacesinOrbit It's meant to look like one. A macro that is meant to look like a declaration should behave like a declaration, i.e. require a trailing semicolon. – Sebastian Redl May 19 '15 at 15:28
  • @SebastianRedl: That seems absurd to me. You're (or the OP is) going out of your way to make a thing look like some other thing, and in doing so introducing a totally reasonable warning, then trying to disable the warning. Everything about this seems strange to me. – Lightness Races in Orbit May 19 '15 at 16:44