0

I stumbled upon some syntactically weird looking code recently when porting a c++ project from Windows to Linux.

if ( isObjectNear( objectPos, objectLength ) + .025, 0.125 ) { ...  }"

In this if-statement a parenthesis was misplaced causing the statement to consist of two expressions separated by the comma. The boolean "isObjectNear(..)" method had default parameters which allowed the call to be made using Microsoft's compiler despite the obvious mistake.

It was when building on Linux with GCC the problem was discovered giving the error message:

error: value computed is not used [-Werror=unused-value]

The code in my case is more interesting than relevant to the question and the following code serve the purpose of the question more clearly with the return-value in comments:

if ( true, 0.5 ) ... // returns true since 0.5 > 0 ( 0 == false)

if ( true, 0.0 ) ... // returns false 

if ( 1.0, false ) ... // returns false

if ( true, false, false, ..., true ) ... // returns true

So back to the question "Why is a if-statement with comma-separated expressions allowed by Microsoft's C/C++ compiler?"

  • Because [comma operator](https://en.wikipedia.org/wiki/Comma_operator). – Paul R Jan 13 '16 at 12:08
  • 4
    It is allowed by GCC. It's just that you have `-Werror` set so the warning is being reported as an error. – Richard Hodges Jan 13 '16 at 12:09
  • 1
    The "comma operator" have passed me by and just like you @PaulR effectively commented explains it all. It's also true that the -Werror flag is set when using the gcc. Thanks for sharing your knowledge! – Jonatan Hägglund Jan 13 '16 at 12:36
  • @JonatanHägglund: yes, it's a common source of errors - more than once i've seen people write things like `if (a > 0, b > 0)` where it should be `if (a > 0 && b > 0)` and since this compiles without error it can lead to nasty latent bugs in some cases. – Paul R Jan 13 '16 at 12:46
  • @AdrianMcCarthy Yes, my mistake! Like I mentioned here in the comments I didn't know about the comma operator until now. I'll remove that line since it's a false statement. Thanks for mentioning it! – Jonatan Hägglund Jan 14 '16 at 12:34
  • @JonatanHägglund: Cool, thanks for fixing that. I've deleted my comment since it no longer applies. – Adrian McCarthy Jan 14 '16 at 18:47

1 Answers1

3

It is allowed because it's syntactically correct and a standard compliant compiler must accept it.

The GNU compiler guesses that throwing away the result of the left hand expression was not intentional and helpfully gives you a warning. You've told the compiler to treat warnings as errors. If you hadn't done so, it would be allowed by gcc too.

The standard does not require the compiler to give a diagnostic when the result of an expression is not used, and Microsoft may have chosen not to do so. Even in gcc, Wunused-value is not enabled even by Wall which suggests that it is considered an option that is likely to have many false-positives. I don't think this case is a false positive, though. It seems to me a clear programmer mistake.

Edit. Apparently msvc also issues a warning, as commented by Richard Crittenden.

eerorika
  • 232,697
  • 12
  • 197
  • 326
  • 1
    "allowed the call to be made using Microsoft's compiler despite the obvious mistake" - this is one of many reasons why it's prudent to avoid Microsoft compilers like the plague. – Richard Hodges Jan 13 '16 at 12:11
  • 1
    Thanks! I had totally missed the "comma operator" and can see where it's useful but also (as in this case) the risk of accepted typos. And it's true that gcc was set to treat warnings as errors. Great to learn something new! – Jonatan Hägglund Jan 13 '16 at 12:29
  • 1
    @RichardHodges it's caught by the MS compiler at warning level 4. – Richard Critten Jan 13 '16 at 14:05
  • Good to know and that it was added to the answer! I hope the question won't make people think that the MS compiler isn't able to detect and give the warning. – Jonatan Hägglund Jan 14 '16 at 12:42