ID:1760184
 
Resolved
Certain assignment operators (*=, /=, |=, &=, and ^=) returned incorrect values when the first operand was null, instead of treating it like 0 as promised by the reference.
BYOND Version:507
Operating System:Lubuntu 14.10, native and Wine 1.6.2
Web Browser:Chrome 39.0.2171.95
Applies to:Dream Daemon
Status: Resolved (508.1295)

This issue has been resolved.
Descriptive Problem Summary:
Certain arithmetic and bitwise operators return values contradictory to the DM reference when the first operand is null

Numbered Steps to Reproduce Problem:
Run the code below

Code Snippet to Reproduce Problem:
world/New()
var/N = null
var/K = 1

world.log << "N: [n(N)]" // *null*
world.log << "K: [n(K)]" // 1

world.log << "N*K: [n(N * K)]; expected 0" // *null*
world.log << "N/K: [n(N / K)]; expected 0" // *null*

N *= K
world.log << "N*=K: [n(N)]; expected 0" // *null*
N = null

N /= K
world.log << "N/=K: [n(N)]; expected 0" // *null*
N = null

N |= K
world.log << "N|=K: [n(N)]; expected 1" // 0
N = null

N ^= K
world.log << "N^=K: [n(N)]; expected 1" // 0
N = null

proc/n(n)
if(n == null) return "*null*"
return n


Expected Results:
For null to behave identically to 0 in all arithmetic and bitwise operations, as specified in the DM reference: "in a numeric context (like a mathematical operation), null evaluates to 0" ( http://www.byond.com/docs/ref/info.html#/DM/null )

Actual Results:
In multiplication and division, null as the first argument causes the result to also be null.
In in-place OR and XOR, null as the initial value of the var causes the final value of the var to be zero.

Does the problem occur:
Every time? Or how often? Every time.
In other games? Not relevant.
In other user accounts? Yes.
On other computers? Yes.

When does the problem NOT occur? Unknown.

Did the problem NOT occur in any earlier versions? If so, what was the last version that worked? (Visit http://www.byond.com/download/build to download old versions for testing.) Unknown.

Workarounds: Explicitly check for null in all usages where it may be the left operand to * or /, and where it may be the value of the variable on the left of |= or ^=. Alternatively, use the form A = A | B instead of A |= B for OR and XOR where A may be null.

Bump?

Still an issue in 508.1294.
I can confirm this is happening. I must've noticed it a long time ago because I always initialize my bit flags to 0.
Nadrew changed status to 'Verified'
While I have minor fear that changing this could impact some games, I suspect it isn't so. I'd appreciate a comprehensive list of where this fails and doesn't, if there are any cases besides the ones presented above--including whether this only happens when null is the first operand.
As far as I know it only happens when the first operand is null instead of 0, as Kaiochao said I've taken to initializing my bitflag variables to 0 no matter what to prevent this. I never considered it a bug.
I'm okay with the current behavior but since the reference says it should be otherwise, I'm cool with changing it.
The multiplication/division behaviour is unexpected but not inherently *wrong*; null in an arithmetic context is equivalent to zero (or should be), so null*N being null is technically correct.

In-place OR/XOR is both unexpected and doesn't follow the reference (or make sense):
var/x = null
x |= 1 // now 0
x |= 2 // now 2
world << x // prints '2'

var/y = 0
y |= 1 // now 1
y |= 2 // now 3
world << y // prints '3'
In response to GinjaNinja32
Lol, pretty sure I came across that a few months ago and couldn't figure out why it was behaving like that. Just decided it wasn't worth it and gave up on the operator.
Lummox JR resolved issue with message:
Certain assignment operators (*=, /=, |=, &=, and ^=) returned incorrect values when the first operand was null, instead of treating it like 0 as promised by the reference.