Adding a ContiguousBytes
protocol is the most logical way to handle containers that can be viewed as contiguous bytes. But there may be some concern about the runtime overhead associated with adding more conformances to generic types. I'm not sure how valid those concerns still are given the current state of runtime optimization. Nonetheless, it's a significant language change.
As of Feb 5, 2022, it is reasonably safe to implement Foundation.Data's withContiguousStorageIfAvailable
by using withMemoryRebound
: SE-0333 Expand usability of withMemoryRebound
It is now legal to pass a Swift UnsafePointer into a C function taking char *
. That solves the problem of calling into (abusive) C APIs that assume char *
can alias with anything.
apple/swift-evolution/blob/main/proposals/0324-c-lang-pointer-arg-conversion.md
# Relax diagnostics for pointer arguments to C functions
* Proposal: [SE-0324](0324-c-lang-pointer-arg-conversion.md)
* Authors: [Andrew Trick](https://github.com/atrick), [Pavel Yaskevich](https://github.com/xedin)
* Review Manager: [Saleem Abdulrasool](https://github.com/compnerd)
* Status: **Implemented (Swift 5.6)**
* Implementation: [apple/swift#37956](https://github.com/apple/swift/pull/37956)
* Decision Notes: [Rationale](https://forums.swift.org/t/accepted-se-0324-relax-diagnostics-for-pointer-arguments-to-c-functions/52599)
* Bugs: [SR-10246](https://bugs.swift.org/browse/SR-10246)
## Introduction
C has special rules for pointer aliasing, for example allowing `char *` to alias other pointer types, and allowing pointers to signed and unsigned types to alias. The usability of some C APIs relies on the ability to easily cast pointers within the boundaries of those rules. Swift generally disallows typed pointer conversion. See [SE-0107 UnsafeRawPointer API](https://github.com/apple/swift-evolution/blob/main/proposals/0107-unsaferawpointer.md). Teaching the Swift compiler to allow pointer conversion within the rules of C when invoking functions imported from C headers will dramatically improve interoperability with no negative impact on type safety.
Swift-evolution thread: [Pitch: Implicit Pointer Conversion for C Interoperability](https://forums.swift.org/t/pitch-implicit-pointer-conversion-for-c-interoperability/51129)
## Motivation
Swift exposes untyped, contiguous byte sequences using `UnsafeRawPointer`. This completely bypasses thorny strict aliasing rules when encoding and decoding byte streams. However, Swift programmers often need to call into low-level C functions to help implement the encoding. Those C functions commonly expect a `char *` pointer rather than a `void *` pointer to the contiguous bytes. Swift does not allow raw pointers to be passed as typed pointers because it can easily introduce undefined behavior.
This file has been truncated. show original
It is extremely important for Swift programmers, whether they are C experts or not, to realize that casting typed pointers is the wrong way to reinterpret types. There is a safe and convenient way to do this using raw pointers. If they see common examples of code converting typed pointers, rather than using raw pointers, then that is actively misleading. It will lead to more undefined behavior in Swift code as they find ways to force the compiler to cast pointers to other types. Special-casing the semantics of Swift's generic unsafe pointer types based on an element type, which is not always known at compile time, would add a bizarre source of complexity to the language.
Remember that it's common for C code to have undefined behavior related to this. People seldom notice this problem because of limited optimization scope across C libraries.