-
Notifications
You must be signed in to change notification settings - Fork 23
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
Deprecate 'unsafeAddr' and make 'addr' available for all addressable locations #369
Comments
I always thought |
@PMunch |
What's the distinction between the two then? |
|
Since Nim identifies its unsafe Correct me if I'm wrong, but besides parameters and |
You're correct and I've updated my description. |
Also, @PMunch, to possibly answer your question a bit more, the primary way in which pointers from You could, for example, accidentally reverse the order of There may be some other way in which it is "more unsafe", but I think this is the primary way I am not sure this analogy will help, but this is sort of why I think the reality there was that validating input is so intertwined with parsing that this is where it happens, but a stdlib marking data "right at the entry point" was a bit too early since a lot of people pass on the data to a few procs before actually validating or pass it to multiple procs and don't always declare proc parameters as With Nim most pointer code is pretty small/confined/easy to reason about (in my experience). Most people using pointers already know (maybe instinctively) to be even more careful about writes than reads. Even otherwise, were the code more "distributed" with lots of proc signatures with The same thing tends to happen with It's actually really tricky to provide people with escape hatches to various guard rails keeping them from driving off the road while also preventing such workarounds from becoming "bad" (or maybe not) habits that undermine the reason for even having the guard in the first place. It tends to happen in every programming language. It's all really a subset of the extremely generic security-convenience trade-off axis. Answers come down to how often certain security mistakes are made in practice, and in programming that usually means "attention". Once you are writing to pointers not reading, many programmers are already paying extra attention already. That is where you can corrupt memory not just fail on a bad read. But even if they weren't the times the distinction could most help have the distinction remote from the mistake. And maybe pointers in Nim are already rare enough to hit attention critical mass anyway. |
Also, I should have said that, for compatibility with old code, I think |
I'm against this RFC, even if everyone else seems to think it's a good idea. But example 1nim r main when true:
let s = "abc".cstring
# s[0].addr[] = 'x' # CT error
s[0].unsafeAddr[] = 'x' # RT error: SIGBUS
echo s example 2nim r -b:js main when true:
type Foo = object
counter: int
proc fn(a: Foo) =
# let b = a.addr # CT error
let b = a.unsafeAddr # RT error below in js: TypeError: Cannot read property 'counter' of undefined
echo b[].counter
echo a
var f: Foo
fn(f) what's worse, the RT error depends on context, eg it disappears if you comment example 3nim r main what worse, this depends on Foo.sizeof; eg with -d:case2a you'd get when defined case2:
type Foo = object
counter: int
when defined case2a:
data: array[100, byte]
proc fn(a: Foo) =
# let b = a.addr # CT error
let b = a.unsafeAddr
b[].counter += 2
proc main =
var f = Foo(counter: 3)
fn(f)
echo f.counter
static: main()
main()
I just showed 3 simple examples above where addr would give CT error and unsafeAddr would give runtime errors or inconsistent results or would depend on seemingly unrelated context; each backend is affected, in different ways: c, js VM. unsafeAddr is a useful escape hatch when you know what you're doing (including compiler implementation details such as sizeof thresholds for pass by value vs by reference), but at least the compiler tells you you're in uncharted territory. If we started to conflate addr and unsafeAddr, you'd lose this distinction and it would make In summary, conflating addr and unsafeAddr doesn't fix any bugs or enable any new features, and it does make the langauge less safe, for no tangible benefit. |
No one ever said It may clarify to discuss the opposite direction of this RFC which relates to this benefit. If Since it is very hard to assess all this objectively (or even systematically) people mostly argue by bald assertion. Here's one - it's already a very bad sign that long-time Nim users need to ask about the distinction. Maybe that happens because pointers are needed so rarely and keeping up that good work however/wherever & making it more rare rather than adding new ones is what matters in the end? |
* implements nim-lang/RFCs#369 * deprecate unsafeAddr; extend addr addr is now available for all addressable locations, unsafeAddr is deprecated and become an alias for addr * follow @Vindaar's advice * change the signature of addr * unsafeAddr => addr (stdlib) * Update changelog.md * unsafeAddr => addr (tests) * Revert "unsafeAddr => addr (stdlib)" This reverts commit ab83c99. * doc changes; thanks to @konsumlamm Co-authored-by: konsumlamm <44230978+konsumlamm@users.noreply.github.com> * merge * remove * fix bug Co-authored-by: Araq <rumpf_a@web.de> Co-authored-by: konsumlamm <44230978+konsumlamm@users.noreply.github.com>
* implements nim-lang/RFCs#369 * deprecate unsafeAddr; extend addr addr is now available for all addressable locations, unsafeAddr is deprecated and become an alias for addr * follow @Vindaar's advice * change the signature of addr * unsafeAddr => addr (stdlib) * Update changelog.md * unsafeAddr => addr (tests) * Revert "unsafeAddr => addr (stdlib)" This reverts commit ab83c99. * doc changes; thanks to @konsumlamm Co-authored-by: konsumlamm <44230978+konsumlamm@users.noreply.github.com> * merge * remove * fix bug Co-authored-by: Araq <rumpf_a@web.de> Co-authored-by: konsumlamm <44230978+konsumlamm@users.noreply.github.com>
As the title says, this is a simple proposal: We allow 'addr' for where 'unsafeAddr' used to be required (consts, let variables, for loop variables and parameters) and deprecate 'unsafeAddr'.
Reasons
The text was updated successfully, but these errors were encountered: