Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Compound assignment operators shouldn't use templates #94

Open
konsumlamm opened this issue Jan 28, 2022 · 8 comments
Open

Compound assignment operators shouldn't use templates #94

konsumlamm opened this issue Jan 28, 2022 · 8 comments

Comments

@konsumlamm
Copy link
Contributor

Currently, e.g. += is defined as

template `+=`*(a: var BigInt, b: BigInt) =
  a = a + b

This causes a to be evaluated twice, which can produce unexpected results, when it's an expression that can cause side effects. For example

proc lol(x: var BigInt): var BigInt =
  echo "hello ", x
  x

var a = 42.initBigInt
lol(a) += 1.initBigInt

prints hello 42 twice, instead of just once.

The solution would be to just make it a func instead. The same applies to -= and *=.

@konsumlamm
Copy link
Contributor Author

As a further point, += etc. in the standard library are also procs/funcs.

@konsumlamm
Copy link
Contributor Author

I tried to implement this, but changing += breaks a test. This is possibly caused by nim-lang/Nim#19464.

@dlesnoff
Copy link
Contributor

Could you tell us which test is broken by this change ?

@konsumlamm
Copy link
Contributor Author

Could you tell us which test is broken by this change ?

The first "off by one in division" test case in tests/tbugs.nim. You can also check this for yourself by simply making += a func.

@dlesnoff
Copy link
Contributor

This is indeed strange, it is off by one like in issue #5 (but one greater than expected result), and only for the static call. Otherwise I didn't encounter any other bugs. We might have a look at the changes of the PR #6 that should have fixed issue #5.

@ringabout
Copy link
Member

update: nim-lang/Nim#19464 is fixed

@dlesnoff
Copy link
Contributor

@konsumlamm Isn't this issue now just a matter of changing template to proc with a :%s/template ′(\c)=′/proc ′$1=′/g (Vim approximative sed regexp to change all template of compound assigments into procs).

@konsumlamm
Copy link
Contributor Author

That fixes the issue for 1.6, but not for 1.4. So there are several possibilities for how to proceed:

  • drop 1.4 support
  • accept that compound assignment operators are buggy for 1.4 (either by keeping them as templates or by changing them to funcs too) - this should only be a temporary solution imo
  • reimplement compound assignments to not copy the first argument (and possibly reimplement + as result = a; result += b) - I think this is the best option in the long run

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants