ID:2374624
 
Resolved
An expression with side effects surrounded by parentheses produced a compiler warning, in situations where the same expression without parentheses didn't.
BYOND Version:512.1426
Operating System:Windows 7 Ultimate 64-bit
Web Browser:Firefox 60.0
Applies to:Dream Maker
Status: Resolved (512.1427)

This issue has been resolved.
Descriptive Problem Summary:
Lone parenthesized ternaries throw compiler warning "warning: : operation has no effect here" even though they work fine otherwise. If it isn't parenthesized or isn't alone on the line (ex: assigned to a var) the compiler doesn't give a warning.

Steps to Reproduce Problem:
The third code snippet can be compiled as is to see the issue yourself. Other than the warning everything works fine.

Code Snippet (if applicable) to Reproduce Problem:
Works fine
name == "test" ? do_foo() : do_bar()

Throws "warning: : operation has no effect here"
(name == "test" ? do_foo() : do_bar())

/proc/do_foo()
usr << "foo"

/proc/do_bar()
usr << "bar"

/mob/verb/test_paren()
(name == "test" ? do_foo() : do_bar())


Expected Results:
No compiler warning

Actual Results:
A compiler warning for functional code

Did the problem NOT occur in any earlier versions? If so, what was the last version that worked?
This is also an issue on 511.1385

Workarounds:
Don't use parentheses. However in the case of a macro that can be used both by itself or in a more complex arrangement you need to have separate macros.
I ran into this recently myself. Didn't wind up pinning it down fully.
What kind of surprises me is that the ternary is allowed to be used this way in the first place. I still have to look into this, but my hunch is that if there's something like a proc call it's being counted as a statement rather than an expression, but the ( operator is causing a nesting effect in which it's assumed to be an expression.

Now that the language rather blurs the difference between statements and expressions, this is definitely on my radar to fix.
The actual use case for this kind of thing is
#define DO_THING (!check() ? FALSE : _do_thing())

Then it can be used in any of these ways
DO_THING

if(DO_THING && foo)
...

var/foo = DO_THING


The first gets warnings if it has parentheses but the second can have problems with order of operations if it isn't. This is blocking some improvements I'd like to make to our ECS system in ss13.
In response to Lummox JR
The minified Runt source (old!) contains code like
condition && Proc()

and I used to write code like that for a while after seeing that it's possible. (I don't do that anymore, though, because readability has been way more important to me since then.)
Can confirm this warning is annoying, our automated test systems treat warnings like errors.

I also don't suppose it would be easy to add a meta sequence to disable a warning on a certain line? c# has that weird [] thing.

Its hard to ignore warnings in post as line numbers can change
Lummox JR resolved issue with message:
An expression with side effects surrounded by parentheses produced a compiler warning, in situations where the same expression without parentheses didn't.