
Swift 3.0 Unsafe World - robjperez
http://technology.meronapps.com/2016/09/27/swift-3-0-unsafe-world-2/
======
gilgoomesh
The article includes the following example:

    
    
        let a = UnsafeMutablePointer<Int>.allocate(capacity: 1)
        a.pointee = 42
    

FYI, you should never do this.

Assignment to the `pointee` is only safe where the `pointee` is already
initialized. If the pointee is uninitialized, you should be using
`initialize`. e.g.

    
    
        let a = UnsafeMutablePointer<Int>.allocate(capacity: 1)
        a.initialize(to: 42)
    

While it doesn't actually matter for `Int`, it _does_ matter for classes,
unspecialized generics and other Swift reference counted types since Swift
will try to _release_ the destination before assigning a new value into it. If
the destination is uninitialized garbage, this can cause a crash or other
misbehavior. Following proper practice is a good idea – even if you're using a
hard coded pure value type like `Int` – since it prevents problems down the
road if you decide to change.

Similarly, you should `deinitialize` the buffer when you're finished, not
simply `deallocate`.

~~~
atrick6
From the doc comments:

    
    
      /// Accesses the `Pointee` instance referenced by `self`.
      ///
      /// - Precondition: Either the pointee has been initialized with an
      ///   instance of type `Pointee`, or `pointee` is being assigned to
      ///   and `Pointee` is a trivial type.
      public var pointee: Pointee
    

So, `a.pointee = 42` is fine since we all know that `Int` is a trivial type.

~~~
nine_k
Jaywalking when a street is empty is safe; it does not mean that jaywalking is
safe _in general_ , and that one should get used to it.

In this case, `.initialize` is likely also _faster_ because any previous-
value-checking logic than might be there is explicitly not used.

~~~
mikeash
When it's explicitly allowed by the rules, it's no longer "jaywalking."

You're right that it doesn't mean this is safe in general, but the original
comment is wrong that you should _never_ do this.

What previous-value-checking logic are you referring to? I would expect
.pointee = 42 to compile down to a single store instruction.

------
Waterluvian
Is garbage collection strictly worse than other memory managementarment
techniques?

Got distracted one sentence in by an assertion that's so at odds with my
understanding of the world.

~~~
adrianm
The Garbage Collection Handbook
[[http://gchandbook.org/](http://gchandbook.org/)] has a good overview of the
advantages and disadvantages of reference counting as garbage collection.

In summary,

Advantages:

A. Objects are collected immediately when they become garbage.

B. Programming language runtime support is simpler.

C. Memory can be reclaimed easily in programs with distributed heaps.

Disadvantages:

A. Natural race conditions exist in multi-threaded programs when reference
counting is used. Atomic read/writes are necessary when
incrementing/decrementing the reference count for an object.

B. Cyclic data structures cannot be reclaimed. (This is why you have to jump
through hoops to avoid this in Objective-C and Swift.)

C. Every object in your language which is reference counted needs a field to
hold the reference count. Or you need a special object in its stead which
"points" to your object, like a shared pointer.

D. Pauses with reference counting are still possible. As stated in the book,
"When the last reference to the head of a large pointer structure is deleted,
reference counting must recursively delete the descendant of the root."

~~~
ridiculous_fish
Two more advantages which are relevant for Swift:

1\. Memory high-water-mark is generally lower with RC, which is important for
mobile.

2\. RC lets you easily determine when there is only one reference to an
object. This enables Swift's collections to be value types, one of Swift's key
semantics.

~~~
masklinn
> 2\. RC lets you easily determine when there is only one reference to an
> object. This enables Swift's collections to be value types, one of Swift's
> key semantics.

It also enables some optimisations e.g. Python has immutable strings, but
CPython can take advantage of rc=1 to extend strings in-place (avoiding
accidentally quadratic concatenation loops until you start storing
intermediate references or you try to run the software on alternate
implementations)

------
alariccole
Great read on a topic I've been looking for more info on, recently coding an
audio app that needs to manipulate audio buffers. And this is the only way to
access them. I've been working in swift since 1.0 and this is the first time
this all makes sense.

~~~
charlesism
It's one of the clearest articles I've read on the subject, too. I would have
liked it if there had been a section on calling "malloc" and "free" directly
from Swift though. I do that a few places in my audio app, and there are a few
gotchas involved (eg: at least in Swift 1, shouldn't use "free" and "dealloc"
interchangeably. Probably still the case).

------
jepler
To someone unfamiliar with swift, it seems quite informative about the
mechanics of unsafe pointers. Where it misses is in discussing how best to
segregate the "parts with unsafe" from "the bulk of your code (hopefully)",
since the parts with unsafe by definition deserve more careful review and
auditing (or even that you _should_ do this sort of segregation)

There are probably many ways you could design the partition; for instance, I
would probably try to design a safe API that was patterned closely after the
underlying one (Posix, OpenGL, etc); others would prefer to design more Swift-
ian APIs that still expose all the useful capabilities of the underlying
libraries.

