# Swift needs fixed-size array

**URL:** <https://forums.swift.org/t/swift-needs-fixed-size-array/5685>\
**Category:** Pitches\
**Created:** [April 17, 2017, 5:52pm UTC](https://forums.swift.org/t/swift-needs-fixed-size-array/5685 "2017-04-17T17:52:01Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![smartgo](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/smartgo/32/344_2.png) [@smartgo](https://forums.swift.org/u/smartgo)\
**Post date:** [April 17, 2017, 5:52pm UTC](https://forums.swift.org/t/swift-needs-fixed-size-array/5685/1 "2017-04-17T17:52:01Z")

</div>

Swift needs a datatype that contains a fixed number of a given type; basically a simple fixed-size array.

Motivation: I’ve been porting code for Monte Carlo Tree Search in my Go-playing program from C++ to Swift. Performance is crucial for this code, as more simulations lead to better play. After the initial port, the Swift code was more than 10x slower than my C++ code. After several weeks of optimizing, profiling, and digging through disassembly, I’ve gotten to within a factor of 2. Most of that gain came from using the ugly workaround of importing fixed-size arrays from C.

My app is designed for a 19x19 (or smaller) Go board, not an arbitrary N x N board, so I don’t want to pay the high cost of variable-size data structures in the lowest levels of my app. Most apps are not like this, and most of my app is not, but this kernel of my app needs to be fast. Heap allocations, reference counting, and indirections all slow down the code. I just need a fixed size of memory that I can access like an array, and Swift doesn’t let me do that.

Workaround: By importing an array from C, I can allocate a blob of memory on the stack or include it in a struct. I can then use UnsafeRawPointer to access that blob like an array (see details in SR-4548). This is ugly, but it works, and it is much faster than using a Swift array. However, I’m stymied by SR-4542, which causes mutability to spread like a plague through client code.

(SR-4542: Calling a function taking an UnsafeRawPointer forces the parameter to be passed as inout, which means the method must be mutating. UnsafeMutableRawPointer should require inout, UnsafeRawPointer should not.)

Proposal: UnsafeMutablePointer almost provides what I need. However, it can only allocate memory on the heap, or it can take a given blob of memory and interpret it as something else. What’s missing is a way to allocate typed memory of a certain size on the stack or in a struct. For example, something like this, with support for subscripts, limited to value types:

&nbsp;&nbsp;&nbsp;&nbsp;var foo = UnsafeMemory\<Int64\>(count: 6)  
or  
&nbsp;&nbsp;&nbsp;&nbsp;var bar = FixedSizeArray\<UInt32\>(repeating: 0, count: 380)

Alternatives:  
(1) C arrays are currently imported as tuples, so extending tuples with subscripts and adding a way to create tuples with a specific count of the same type could address this need. However, I don’t think this fits well with the concept of tuples.  
(2) Changing the Array type to allow a fixed size could be considered in the future. ‘count’ and ‘capacity’ would be fixed and only known to the compiler, not stored with the data. However, I suspect the consequences would be far-reaching, and thus I don’t see this happening soon.

An UnsafeMemory type would be a limited addition that fits in well with the existing low-level Pointer module, and fills a gap in the capabilities of Swift. The Pointer module helps implement low-level, performance-critical code, and not being able to create data on the stack is a serious omission. Jumping through C hoops is not a solution.

Anders Kierulf

---

<div class="post-metadata">

**Author:** ![David\_Sweeris](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/david_sweeris/32/31302_2.png) [@David\_Sweeris](https://forums.swift.org/u/David_Sweeris)\
**Post date:** [April 17, 2017, 6:37pm UTC](https://forums.swift.org/t/swift-needs-fixed-size-array/5685/2 "2017-04-17T18:37:47Z")

</div>

Up until 30 seconds ago, I'd thought there was a way to initialize an array with a pre-existing buffer. Apparently not, though.

There’s currently no way to restrict a generic parameter to be a value type. I suspect this is at least partly because `struct` doesn’t make any promises about whether its properties have value or reference semantics (but unless I’m forgetting something, that’s just a guess on my part). The topic of an exclusively value-semantics type, “simplestruct” for lack of a better term, has come up at least once. IIRC it was deemed to not provide enough of a benefit to justify the added language complexity (although I have a vague memory that it was only brought in connection with another topic, as it is here, so maybe if it was its own proposal the results would been different). Personally, I don’t think it adds all that much complexity (from the developer's PoV… dunno about the compiler), and barring some other reason would be in favor of it. That’s just one opinion, though (and one of someone who’s not all that experienced, as well).

Both of your alternatives have been brought up before. My recollection is we tentatively\* decided that it’d be better to add fixed-size arrays and change how C arrays are imported, but that conversation was a \*long\* time ago, before we were as worried about backwards compatibility. Neither alternative has come to a formal proposal, though, because they were deemed out-of-scope\*\* before things got that far. I don’t think either has come up since phase 2 started, though... Maybe it’d be worth revisiting the ideas?

- Dave Sweeris

\* because of \*\*

> **···**
>
> > On Apr 17, 2017, at 10:52 AM, Anders Kierulf via swift-evolution \<swift-evolution@swift.org\> wrote:
> > 
> > Swift needs a datatype that contains a fixed number of a given type; basically a simple fixed-size array.
> > 
> > Motivation: I’ve been porting code for Monte Carlo Tree Search in my Go-playing program from C++ to Swift. Performance is crucial for this code, as more simulations lead to better play. After the initial port, the Swift code was more than 10x slower than my C++ code. After several weeks of optimizing, profiling, and digging through disassembly, I’ve gotten to within a factor of 2. Most of that gain came from using the ugly workaround of importing fixed-size arrays from C.
> > 
> > My app is designed for a 19x19 (or smaller) Go board, not an arbitrary N x N board, so I don’t want to pay the high cost of variable-size data structures in the lowest levels of my app. Most apps are not like this, and most of my app is not, but this kernel of my app needs to be fast. Heap allocations, reference counting, and indirections all slow down the code. I just need a fixed size of memory that I can access like an array, and Swift doesn’t let me do that.
> > 
> > Workaround: By importing an array from C, I can allocate a blob of memory on the stack or include it in a struct. I can then use UnsafeRawPointer to access that blob like an array (see details in SR-4548). This is ugly, but it works, and it is much faster than using a Swift array. However, I’m stymied by SR-4542, which causes mutability to spread like a plague through client code.
> > 
> > (SR-4542: Calling a function taking an UnsafeRawPointer forces the parameter to be passed as inout, which means the method must be mutating. UnsafeMutableRawPointer should require inout, UnsafeRawPointer should not.)
> > 
> > Proposal: UnsafeMutablePointer almost provides what I need. However, it can only allocate memory on the heap, or it can take a given blob of memory and interpret it as something else. What’s missing is a way to allocate typed memory of a certain size on the stack or in a struct. For example, something like this, with support for subscripts, limited to value types:
> > 
> > &nbsp;&nbsp;&nbsp;var foo = UnsafeMemory\<Int64\>(count: 6)  
> > or  
> > &nbsp;&nbsp;&nbsp;var bar = FixedSizeArray\<UInt32\>(repeating: 0, count: 380)
> > 
> > Alternatives:  
> > (1) C arrays are currently imported as tuples, so extending tuples with subscripts and adding a way to create tuples with a specific count of the same type could address this need. However, I don’t think this fits well with the concept of tuples.  
> > (2) Changing the Array type to allow a fixed size could be considered in the future. ‘count’ and ‘capacity’ would be fixed and only known to the compiler, not stored with the data. However, I suspect the consequences would be far-reaching, and thus I don’t see this happening soon.
> > 
> > An UnsafeMemory type would be a limited addition that fits in well with the existing low-level Pointer module, and fills a gap in the capabilities of Swift. The Pointer module helps implement low-level, performance-critical code, and not being able to create data on the stack is a serious omission. Jumping through C hoops is not a solution.

---

<div class="post-metadata">

**Author:** ![Karl](https://avatars.discourse-cdn.com/v4/letter/k/34f0e0/32.png) [@Karl](https://forums.swift.org/u/Karl)\
**Post date:** [April 17, 2017, 6:37pm UTC](https://forums.swift.org/t/swift-needs-fixed-size-array/5685/3 "2017-04-17T18:37:21Z")

</div>

What happens if you use alloca?

> **···**
>
> > On 17 Apr 2017, at 19:52, Anders Kierulf via swift-evolution \<swift-evolution@swift.org\> wrote:
> > 
> > Proposal: UnsafeMutablePointer almost provides what I need. However, it can only allocate memory on the heap, or it can take a given blob of memory and interpret it as something else. What’s missing is a way to allocate typed memory of a certain size on the stack or in a struct. For example, something like this, with support for subscripts, limited to value types:

---

<div class="post-metadata">

**Author:** ![Jens](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/jens/32/12903_2.png) [@Jens](https://forums.swift.org/u/Jens)\
**Post date:** [April 17, 2017, 9:07pm UTC](https://forums.swift.org/t/swift-needs-fixed-size-array/5685/4 "2017-04-17T21:07:53Z")

</div>

I've used code like the following example in similar situations and I've  
always (after a lot of profiling, trial and error) managed to get the  
(ugly) Swift code as fast as the C/C++ code.

struct UnsafeStatic19x19\<E\> {  
&nbsp;&nbsp;&nbsp;&nbsp;var storage: (  
&nbsp;&nbsp;&nbsp;&nbsp;E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E,  
&nbsp;&nbsp;&nbsp;&nbsp;E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E,  
&nbsp;&nbsp;&nbsp;&nbsp;E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E,  
&nbsp;&nbsp;&nbsp;&nbsp;E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E,  
&nbsp;&nbsp;&nbsp;&nbsp;E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E,  
&nbsp;&nbsp;&nbsp;&nbsp;E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E,  
&nbsp;&nbsp;&nbsp;&nbsp;E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E,  
&nbsp;&nbsp;&nbsp;&nbsp;E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E,  
&nbsp;&nbsp;&nbsp;&nbsp;E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E,  
&nbsp;&nbsp;&nbsp;&nbsp;E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E,  
&nbsp;&nbsp;&nbsp;&nbsp;E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E,  
&nbsp;&nbsp;&nbsp;&nbsp;E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E,  
&nbsp;&nbsp;&nbsp;&nbsp;E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E,  
&nbsp;&nbsp;&nbsp;&nbsp;E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E,  
&nbsp;&nbsp;&nbsp;&nbsp;E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E,  
&nbsp;&nbsp;&nbsp;&nbsp;E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E,  
&nbsp;&nbsp;&nbsp;&nbsp;E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E,  
&nbsp;&nbsp;&nbsp;&nbsp;E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E,  
&nbsp;&nbsp;&nbsp;&nbsp;E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E  
&nbsp;&nbsp;&nbsp;&nbsp;)  
&nbsp;&nbsp;&nbsp;&nbsp;subscript(x: Int, y: Int) -\> E {  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;get {  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// No index out of bounds check  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var m = self // \<-- This workaround will be optimized away.  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return withUnsafeBytes(of: &m) {  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;let byteOffset = MemoryLayout\<E\>.stride \* (x + y\*19)  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return $0.load(fromByteOffset: byteOffset, as: E.self)  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;set {  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;withUnsafeMutableBytes(of: &self) {  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;let byteOffset = MemoryLayout\<E\>.stride \* (x + y\*19)  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$0.storeBytes(of: newValue, toByteOffset: byteOffset, as:  
E.self)  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}  
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}  
&nbsp;&nbsp;&nbsp;&nbsp;}  
}

It isn't pretty but it works (haven't tried this code example though, but  
you get the idea).

I wish it was possible to write something like  
struct StaticArray\<Element, Count\> {  
&nbsp;&nbsp;&nbsp;&nbsp;...  
}  
instead (a statically allocated array with type-level Count as well as  
Element).

/Jens

> **···**
>
> On Mon, Apr 17, 2017 at 7:52 PM, Anders Kierulf via swift-evolution \< swift-evolution@swift.org\> wrote:
> 
> > Swift needs a datatype that contains a fixed number of a given type;  
> > basically a simple fixed-size array.
> > 
> > Motivation: I’ve been porting code for Monte Carlo Tree Search in my  
> > Go-playing program from C++ to Swift. Performance is crucial for this code,  
> > as more simulations lead to better play. After the initial port, the Swift  
> > code was more than 10x slower than my C++ code. After several weeks of  
> > optimizing, profiling, and digging through disassembly, I’ve gotten to  
> > within a factor of 2. Most of that gain came from using the ugly workaround  
> > of importing fixed-size arrays from C.
> > 
> > My app is designed for a 19x19 (or smaller) Go board, not an arbitrary N x  
> > N board, so I don’t want to pay the high cost of variable-size data  
> > structures in the lowest levels of my app. Most apps are not like this, and  
> > most of my app is not, but this kernel of my app needs to be fast. Heap  
> > allocations, reference counting, and indirections all slow down the code. I  
> > just need a fixed size of memory that I can access like an array, and Swift  
> > doesn’t let me do that.
> > 
> > Workaround: By importing an array from C, I can allocate a blob of memory  
> > on the stack or include it in a struct. I can then use UnsafeRawPointer to  
> > access that blob like an array (see details in SR-4548). This is ugly, but  
> > it works, and it is much faster than using a Swift array. However, I’m  
> > stymied by SR-4542, which causes mutability to spread like a plague through  
> > client code.
> > 
> > (SR-4542: Calling a function taking an UnsafeRawPointer forces the  
> > parameter to be passed as inout, which means the method must be mutating.  
> > UnsafeMutableRawPointer should require inout, UnsafeRawPointer should not.)
> > 
> > Proposal: UnsafeMutablePointer almost provides what I need. However, it  
> > can only allocate memory on the heap, or it can take a given blob of memory  
> > and interpret it as something else. What’s missing is a way to allocate  
> > typed memory of a certain size on the stack or in a struct. For example,  
> > something like this, with support for subscripts, limited to value types:
> > 
> > &nbsp;&nbsp;&nbsp;&nbsp;var foo = UnsafeMemory\<Int64\>(count: 6)  
> > or  
> > &nbsp;&nbsp;&nbsp;&nbsp;var bar = FixedSizeArray\<UInt32\>(repeating: 0, count: 380)
> > 
> > Alternatives:  
> > (1) C arrays are currently imported as tuples, so extending tuples with  
> > subscripts and adding a way to create tuples with a specific count of the  
> > same type could address this need. However, I don’t think this fits well  
> > with the concept of tuples.  
> > (2) Changing the Array type to allow a fixed size could be considered in  
> > the future. ‘count’ and ‘capacity’ would be fixed and only known to the  
> > compiler, not stored with the data. However, I suspect the consequences  
> > would be far-reaching, and thus I don’t see this happening soon.
> > 
> > An UnsafeMemory type would be a limited addition that fits in well with  
> > the existing low-level Pointer module, and fills a gap in the capabilities  
> > of Swift. The Pointer module helps implement low-level,  
> > performance-critical code, and not being able to create data on the stack  
> > is a serious omission. Jumping through C hoops is not a solution.
> > 
> > Anders Kierulf
> > 
> > \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
> > swift-evolution mailing list  
> > swift-evolution@swift.org  
> > [https://lists.swift.org/mailman/listinfo/swift-evolution](https://lists.swift.org/mailman/listinfo/swift-evolution)

---

<div class="post-metadata">

**Author:** ![smartgo](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/smartgo/32/344_2.png) [@smartgo](https://forums.swift.org/u/smartgo)\
**Post date:** [April 17, 2017, 7:18pm UTC](https://forums.swift.org/t/swift-needs-fixed-size-array/5685/5 "2017-04-17T19:18:23Z")

</div>

Doesn’t look like using alloca is recommended in Swift: [[SR-323] Using alloca function in Swift results in linker error · Issue #42945 · apple/swift · GitHub](https://bugs.swift.org/browse/SR-323)

Also, while it might be used as a hack for stack allocations, it wouldn’t allow inclusion into structs.

Anders

> **···**
>
> > On Apr 17, 2017, at 12:37 PM, Karl Wagner \<razielim@gmail.com\> wrote:
> > 
> > > On 17 Apr 2017, at 19:52, Anders Kierulf via swift-evolution \<swift-evolution@swift.org \<mailto:swift-evolution@swift.org\>\> wrote:
> > > 
> > > Proposal: UnsafeMutablePointer almost provides what I need. However, it can only allocate memory on the heap, or it can take a given blob of memory and interpret it as something else. What’s missing is a way to allocate typed memory of a certain size on the stack or in a struct. For example, something like this, with support for subscripts, limited to value types:
> > 
> > What happens if you use alloca?

---

<div class="post-metadata">

**Author:** ![Michael\_Ilseman](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/michael_ilseman/32/44640_2.png) [@Michael\_Ilseman](https://forums.swift.org/u/Michael_Ilseman)\
**Post date:** [April 17, 2017, 9:18pm UTC](https://forums.swift.org/t/swift-needs-fixed-size-array/5685/6 "2017-04-17T21:18:57Z")

</div>

This is the best approach that I’m aware of. It does bake in an ABI assumption that the tuple layout will be contiguous and strided/addressable. Monitor [[SR-3726] Define layout algorithm for tuples · Issue #46311 · apple/swift · GitHub](https://bugs.swift.org/browse/SR-3726) for changes here. Note that you can also a little more “pure” in a sense if you construct an UnsafeBufferPointer from your UnsafeRawPointer and operate on that. Currently, the compiler does not always elide the copy in the getter, see [[SR-4581] Optimizer doesn't elide copy · Issue #47158 · apple/swift · GitHub](https://bugs.swift.org/browse/SR-4581)

> **···**
>
> > On Apr 17, 2017, at 2:07 PM, Jens Persson via swift-evolution \<swift-evolution@swift.org\> wrote:
> > 
> > I've used code like the following example in similar situations and I've always (after a lot of profiling, trial and error) managed to get the (ugly) Swift code as fast as the C/C++ code.
> > 
> > struct UnsafeStatic19x19\<E\> {  
> > &nbsp;&nbsp;&nbsp;&nbsp;var storage: (  
> > &nbsp;&nbsp;&nbsp;&nbsp;E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E,  
> > &nbsp;&nbsp;&nbsp;&nbsp;E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E,  
> > &nbsp;&nbsp;&nbsp;&nbsp;E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E,  
> > &nbsp;&nbsp;&nbsp;&nbsp;E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E,  
> > &nbsp;&nbsp;&nbsp;&nbsp;E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E,  
> > &nbsp;&nbsp;&nbsp;&nbsp;E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E,  
> > &nbsp;&nbsp;&nbsp;&nbsp;E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E,  
> > &nbsp;&nbsp;&nbsp;&nbsp;E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E,  
> > &nbsp;&nbsp;&nbsp;&nbsp;E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E,  
> > &nbsp;&nbsp;&nbsp;&nbsp;E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E,  
> > &nbsp;&nbsp;&nbsp;&nbsp;E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E,  
> > &nbsp;&nbsp;&nbsp;&nbsp;E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E,  
> > &nbsp;&nbsp;&nbsp;&nbsp;E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E,  
> > &nbsp;&nbsp;&nbsp;&nbsp;E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E,  
> > &nbsp;&nbsp;&nbsp;&nbsp;E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E,  
> > &nbsp;&nbsp;&nbsp;&nbsp;E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E,  
> > &nbsp;&nbsp;&nbsp;&nbsp;E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E,  
> > &nbsp;&nbsp;&nbsp;&nbsp;E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E,  
> > &nbsp;&nbsp;&nbsp;&nbsp;E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E  
> > &nbsp;&nbsp;&nbsp;&nbsp;)  
> > &nbsp;&nbsp;&nbsp;&nbsp;subscript(x: Int, y: Int) -\> E {  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;get {  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// No index out of bounds check  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var m = self // \<-- This workaround will be optimized away.  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return withUnsafeBytes(of: &m) {  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;let byteOffset = MemoryLayout\<E\>.stride \* (x + y\*19)  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return $0.load(fromByteOffset: byteOffset, as: E.self)  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;set {  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;withUnsafeMutableBytes(of: &self) {  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;let byteOffset = MemoryLayout\<E\>.stride \* (x + y\*19)  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$0.storeBytes(of: newValue, toByteOffset: byteOffset, as: E.self)  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}  
> > &nbsp;&nbsp;&nbsp;&nbsp;}  
> > }
> > 
> > It isn't pretty but it works (haven't tried this code example though, but you get the idea).
> > 
> > I wish it was possible to write something like  
> > struct StaticArray\<Element, Count\> {  
> > &nbsp;&nbsp;&nbsp;&nbsp;...  
> > }  
> > instead (a statically allocated array with type-level Count as well as Element).
> > 
> > /Jens
> > 
> > On Mon, Apr 17, 2017 at 7:52 PM, Anders Kierulf via swift-evolution \<swift-evolution@swift.org \<mailto:swift-evolution@swift.org\>\> wrote:  
> > Swift needs a datatype that contains a fixed number of a given type; basically a simple fixed-size array.
> > 
> > Motivation: I’ve been porting code for Monte Carlo Tree Search in my Go-playing program from C++ to Swift. Performance is crucial for this code, as more simulations lead to better play. After the initial port, the Swift code was more than 10x slower than my C++ code. After several weeks of optimizing, profiling, and digging through disassembly, I’ve gotten to within a factor of 2. Most of that gain came from using the ugly workaround of importing fixed-size arrays from C.
> > 
> > My app is designed for a 19x19 (or smaller) Go board, not an arbitrary N x N board, so I don’t want to pay the high cost of variable-size data structures in the lowest levels of my app. Most apps are not like this, and most of my app is not, but this kernel of my app needs to be fast. Heap allocations, reference counting, and indirections all slow down the code. I just need a fixed size of memory that I can access like an array, and Swift doesn’t let me do that.
> > 
> > Workaround: By importing an array from C, I can allocate a blob of memory on the stack or include it in a struct. I can then use UnsafeRawPointer to access that blob like an array (see details in SR-4548). This is ugly, but it works, and it is much faster than using a Swift array. However, I’m stymied by SR-4542, which causes mutability to spread like a plague through client code.
> > 
> > (SR-4542: Calling a function taking an UnsafeRawPointer forces the parameter to be passed as inout, which means the method must be mutating. UnsafeMutableRawPointer should require inout, UnsafeRawPointer should not.)
> > 
> > Proposal: UnsafeMutablePointer almost provides what I need. However, it can only allocate memory on the heap, or it can take a given blob of memory and interpret it as something else. What’s missing is a way to allocate typed memory of a certain size on the stack or in a struct. For example, something like this, with support for subscripts, limited to value types:
> > 
> > &nbsp;&nbsp;&nbsp;&nbsp;var foo = UnsafeMemory\<Int64\>(count: 6)  
> > or  
> > &nbsp;&nbsp;&nbsp;&nbsp;var bar = FixedSizeArray\<UInt32\>(repeating: 0, count: 380)
> > 
> > Alternatives:  
> > (1) C arrays are currently imported as tuples, so extending tuples with subscripts and adding a way to create tuples with a specific count of the same type could address this need. However, I don’t think this fits well with the concept of tuples.  
> > (2) Changing the Array type to allow a fixed size could be considered in the future. ‘count’ and ‘capacity’ would be fixed and only known to the compiler, not stored with the data. However, I suspect the consequences would be far-reaching, and thus I don’t see this happening soon.
> > 
> > An UnsafeMemory type would be a limited addition that fits in well with the existing low-level Pointer module, and fills a gap in the capabilities of Swift. The Pointer module helps implement low-level, performance-critical code, and not being able to create data on the stack is a serious omission. Jumping through C hoops is not a solution.
> > 
> > Anders Kierulf
> > 
> > \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
> > swift-evolution mailing list  
> > swift-evolution@swift.org \<mailto:swift-evolution@swift.org\>  
> > [https://lists.swift.org/mailman/listinfo/swift-evolution](https://lists.swift.org/mailman/listinfo/swift-evolution)
> > 
> > \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
> > swift-evolution mailing list  
> > swift-evolution@swift.org  
> > [https://lists.swift.org/mailman/listinfo/swift-evolution](https://lists.swift.org/mailman/listinfo/swift-evolution)

---

<div class="post-metadata">

**Author:** ![rxwei](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/rxwei/32/664_2.png) [@rxwei](https://forums.swift.org/u/rxwei)\
**Post date:** [April 17, 2017, 9:18pm UTC](https://forums.swift.org/t/swift-needs-fixed-size-array/5685/7 "2017-04-17T21:18:40Z")

</div>

Huge +1. We definitely need fixed-size arrays. Just in addition to elegantly importing C arrays, this will enable static matrix/tensor shapes for shape-safe compute operations like GEMM. Moreover I think we can learn from Rust about their recent discussion on constant generics.

-Richard

> **···**
>
> > On Apr 17, 2017, at 16:07, Jens Persson via swift-evolution \<swift-evolution@swift.org\> wrote:
> > 
> > I've used code like the following example in similar situations and I've always (after a lot of profiling, trial and error) managed to get the (ugly) Swift code as fast as the C/C++ code.
> > 
> > struct UnsafeStatic19x19\<E\> {  
> > &nbsp;&nbsp;&nbsp;&nbsp;var storage: (  
> > &nbsp;&nbsp;&nbsp;&nbsp;E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E,  
> > &nbsp;&nbsp;&nbsp;&nbsp;E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E,  
> > &nbsp;&nbsp;&nbsp;&nbsp;E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E,  
> > &nbsp;&nbsp;&nbsp;&nbsp;E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E,  
> > &nbsp;&nbsp;&nbsp;&nbsp;E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E,  
> > &nbsp;&nbsp;&nbsp;&nbsp;E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E,  
> > &nbsp;&nbsp;&nbsp;&nbsp;E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E,  
> > &nbsp;&nbsp;&nbsp;&nbsp;E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E,  
> > &nbsp;&nbsp;&nbsp;&nbsp;E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E,  
> > &nbsp;&nbsp;&nbsp;&nbsp;E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E,  
> > &nbsp;&nbsp;&nbsp;&nbsp;E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E,  
> > &nbsp;&nbsp;&nbsp;&nbsp;E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E,  
> > &nbsp;&nbsp;&nbsp;&nbsp;E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E,  
> > &nbsp;&nbsp;&nbsp;&nbsp;E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E,  
> > &nbsp;&nbsp;&nbsp;&nbsp;E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E,  
> > &nbsp;&nbsp;&nbsp;&nbsp;E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E,  
> > &nbsp;&nbsp;&nbsp;&nbsp;E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E,  
> > &nbsp;&nbsp;&nbsp;&nbsp;E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E,  
> > &nbsp;&nbsp;&nbsp;&nbsp;E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E  
> > &nbsp;&nbsp;&nbsp;&nbsp;)  
> > &nbsp;&nbsp;&nbsp;&nbsp;subscript(x: Int, y: Int) -\> E {  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;get {  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// No index out of bounds check  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var m = self // \<-- This workaround will be optimized away.  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return withUnsafeBytes(of: &m) {  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;let byteOffset = MemoryLayout\<E\>.stride \* (x + y\*19)  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return $0.load(fromByteOffset: byteOffset, as: E.self)  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;set {  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;withUnsafeMutableBytes(of: &self) {  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;let byteOffset = MemoryLayout\<E\>.stride \* (x + y\*19)  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$0.storeBytes(of: newValue, toByteOffset: byteOffset, as: E.self)  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}  
> > &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}  
> > &nbsp;&nbsp;&nbsp;&nbsp;}  
> > }
> > 
> > It isn't pretty but it works (haven't tried this code example though, but you get the idea).
> > 
> > I wish it was possible to write something like  
> > struct StaticArray\<Element, Count\> {  
> > &nbsp;&nbsp;&nbsp;&nbsp;...  
> > }  
> > instead (a statically allocated array with type-level Count as well as Element).
> > 
> > /Jens
> > 
> > On Mon, Apr 17, 2017 at 7:52 PM, Anders Kierulf via swift-evolution \<swift-evolution@swift.org \<mailto:swift-evolution@swift.org\>\> wrote:  
> > Swift needs a datatype that contains a fixed number of a given type; basically a simple fixed-size array.
> > 
> > Motivation: I’ve been porting code for Monte Carlo Tree Search in my Go-playing program from C++ to Swift. Performance is crucial for this code, as more simulations lead to better play. After the initial port, the Swift code was more than 10x slower than my C++ code. After several weeks of optimizing, profiling, and digging through disassembly, I’ve gotten to within a factor of 2. Most of that gain came from using the ugly workaround of importing fixed-size arrays from C.
> > 
> > My app is designed for a 19x19 (or smaller) Go board, not an arbitrary N x N board, so I don’t want to pay the high cost of variable-size data structures in the lowest levels of my app. Most apps are not like this, and most of my app is not, but this kernel of my app needs to be fast. Heap allocations, reference counting, and indirections all slow down the code. I just need a fixed size of memory that I can access like an array, and Swift doesn’t let me do that.
> > 
> > Workaround: By importing an array from C, I can allocate a blob of memory on the stack or include it in a struct. I can then use UnsafeRawPointer to access that blob like an array (see details in SR-4548). This is ugly, but it works, and it is much faster than using a Swift array. However, I’m stymied by SR-4542, which causes mutability to spread like a plague through client code.
> > 
> > (SR-4542: Calling a function taking an UnsafeRawPointer forces the parameter to be passed as inout, which means the method must be mutating. UnsafeMutableRawPointer should require inout, UnsafeRawPointer should not.)
> > 
> > Proposal: UnsafeMutablePointer almost provides what I need. However, it can only allocate memory on the heap, or it can take a given blob of memory and interpret it as something else. What’s missing is a way to allocate typed memory of a certain size on the stack or in a struct. For example, something like this, with support for subscripts, limited to value types:
> > 
> > &nbsp;&nbsp;&nbsp;&nbsp;var foo = UnsafeMemory\<Int64\>(count: 6)  
> > or  
> > &nbsp;&nbsp;&nbsp;&nbsp;var bar = FixedSizeArray\<UInt32\>(repeating: 0, count: 380)
> > 
> > Alternatives:  
> > (1) C arrays are currently imported as tuples, so extending tuples with subscripts and adding a way to create tuples with a specific count of the same type could address this need. However, I don’t think this fits well with the concept of tuples.  
> > (2) Changing the Array type to allow a fixed size could be considered in the future. ‘count’ and ‘capacity’ would be fixed and only known to the compiler, not stored with the data. However, I suspect the consequences would be far-reaching, and thus I don’t see this happening soon.
> > 
> > An UnsafeMemory type would be a limited addition that fits in well with the existing low-level Pointer module, and fills a gap in the capabilities of Swift. The Pointer module helps implement low-level, performance-critical code, and not being able to create data on the stack is a serious omission. Jumping through C hoops is not a solution.
> > 
> > Anders Kierulf
> > 
> > \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
> > swift-evolution mailing list  
> > swift-evolution@swift.org \<mailto:swift-evolution@swift.org\>  
> > [https://lists.swift.org/mailman/listinfo/swift-evolution](https://lists.swift.org/mailman/listinfo/swift-evolution)
> > 
> > \_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_\_  
> > swift-evolution mailing list  
> > swift-evolution@swift.org  
> > [https://lists.swift.org/mailman/listinfo/swift-evolution](https://lists.swift.org/mailman/listinfo/swift-evolution)

---

<div class="post-metadata">

**Author:** ![Karl](https://avatars.discourse-cdn.com/v4/letter/k/34f0e0/32.png) [@Karl](https://forums.swift.org/u/Karl)\
**Post date:** [April 17, 2017, 7:33pm UTC](https://forums.swift.org/t/swift-needs-fixed-size-array/5685/8 "2017-04-17T19:33:09Z")

</div>

Huh. That’s weird. I figured in your case, with an integer literal, there shouldn’t really be any difference between alloca(19\*19) and a stack-allocated, fixed-size array like char[19 \* 19].

alloca is usually a compiler intrinsic (I suppose that’s why the linker isn’t going to find it). It’s definitely a SIL intrinsic. Maybe those two just aren’t wired up correctly to support user-code calling “alloca”.

Could certainly be supported - we should probably support alloca directly (as we do for malloc), and we could provide a function on UMP which does the same thing (allocateNonEscaping?)

- Karl

> **···**
>
> > On 17 Apr 2017, at 21:18, Anders Kierulf \<anders@smartgo.com\> wrote:
> > 
> > > On Apr 17, 2017, at 12:37 PM, Karl Wagner \<razielim@gmail.com \<mailto:razielim@gmail.com\>\> wrote:
> > > 
> > > > On 17 Apr 2017, at 19:52, Anders Kierulf via swift-evolution \<swift-evolution@swift.org \<mailto:swift-evolution@swift.org\>\> wrote:
> > > > 
> > > > Proposal: UnsafeMutablePointer almost provides what I need. However, it can only allocate memory on the heap, or it can take a given blob of memory and interpret it as something else. What’s missing is a way to allocate typed memory of a certain size on the stack or in a struct. For example, something like this, with support for subscripts, limited to value types:
> > > 
> > > What happens if you use alloca?
> > 
> > Doesn’t look like using alloca is recommended in Swift: [[SR-323] Using alloca function in Swift results in linker error · Issue #42945 · apple/swift · GitHub](https://bugs.swift.org/browse/SR-323)
> > 
> > Also, while it might be used as a hack for stack allocations, it wouldn’t allow inclusion into structs.
> > 
> > Anders

---

<div class="post-metadata">

**Author:** ![Karl](https://avatars.discourse-cdn.com/v4/letter/k/34f0e0/32.png) [@Karl](https://forums.swift.org/u/Karl)\
**Post date:** [April 17, 2017, 10:29pm UTC](https://forums.swift.org/t/swift-needs-fixed-size-array/5685/9 "2017-04-17T22:29:10Z")

</div>

Will the compiler ever optimise an UBP allocation on to the stack? For example, I’ve written plenty of code such as:

let ptr = UnsafeRawBufferPointer.allocate(count: 128)  
defer { ptr.deallocate(count: 128) }

...when interfacing with C APIs. Which is basically the definition of a stack allocation. That would perhaps be the “swiftier” way to do it; to let the compiler determine how to allocate the memory based on what it knows about its expected lifetime.

> **···**
>
> > On 17 Apr 2017, at 23:18, Michael Ilseman via swift-evolution \<swift-evolution@swift.org\> wrote:
> > 
> > This is the best approach that I’m aware of. It does bake in an ABI assumption that the tuple layout will be contiguous and strided/addressable. Monitor [[SR-3726] Define layout algorithm for tuples · Issue #46311 · apple/swift · GitHub](https://bugs.swift.org/browse/SR-3726) for changes here. Note that you can also a little more “pure” in a sense if you construct an UnsafeBufferPointer from your UnsafeRawPointer and operate on that. Currently, the compiler does not always elide the copy in the getter, see [[SR-4581] Optimizer doesn't elide copy · Issue #47158 · apple/swift · GitHub](https://bugs.swift.org/browse/SR-4581)

---

<div class="post-metadata">

**Author:** ![Michael\_Ilseman](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/michael_ilseman/32/44640_2.png) [@Michael\_Ilseman](https://forums.swift.org/u/Michael_Ilseman)\
**Post date:** [April 17, 2017, 10:58pm UTC](https://forums.swift.org/t/swift-needs-fixed-size-array/5685/10 "2017-04-17T22:58:09Z")

</div>

My understanding is that there is no mechanism yet to guarantee stack allocation for anything.

> **···**
>
> > On Apr 17, 2017, at 3:29 PM, Karl Wagner \<razielim@gmail.com\> wrote:
> > 
> > > On 17 Apr 2017, at 23:18, Michael Ilseman via swift-evolution \<swift-evolution@swift.org \<mailto:swift-evolution@swift.org\>\> wrote:
> > > 
> > > This is the best approach that I’m aware of. It does bake in an ABI assumption that the tuple layout will be contiguous and strided/addressable. Monitor [[SR-3726] Define layout algorithm for tuples · Issue #46311 · apple/swift · GitHub](https://bugs.swift.org/browse/SR-3726) for changes here. Note that you can also a little more “pure” in a sense if you construct an UnsafeBufferPointer from your UnsafeRawPointer and operate on that. Currently, the compiler does not always elide the copy in the getter, see [[SR-4581] Optimizer doesn't elide copy · Issue #47158 · apple/swift · GitHub](https://bugs.swift.org/browse/SR-4581)
> > 
> > Will the compiler ever optimise an UBP allocation on to the stack? For example, I’ve written plenty of code such as:
> > 
> > let ptr = UnsafeRawBufferPointer.allocate(count: 128)  
> > defer { ptr.deallocate(count: 128) }
> > 
> > ...when interfacing with C APIs. Which is basically the definition of a stack allocation. That would perhaps be the “swiftier” way to do it; to let the compiler determine how to allocate the memory based on what it knows about its expected lifetime.

---

<div class="post-metadata">

**Author:** ![Karl](https://avatars.discourse-cdn.com/v4/letter/k/34f0e0/32.png) [@Karl](https://forums.swift.org/u/Karl)\
**Post date:** [April 17, 2017, 10:51pm UTC](https://forums.swift.org/t/swift-needs-fixed-size-array/5685/11 "2017-04-17T22:51:33Z")

</div>

I’ll answer that: no, it won’t.

echo "let ptr = UnsafeMutableRawPointer.allocate(bytes: 128, alignedTo: 1); defer { ptr.deallocate(bytes: 128, alignedTo: 1) }" | swiftc -O -emit-assembly -

&nbsp;&nbsp;.section \_\_TEXT,\_\_text,regular,pure\_instructions  
&nbsp;&nbsp;.macosx\_version\_min 10, 9  
&nbsp;&nbsp;.globl \_main  
&nbsp;&nbsp;.p2align 4, 0x90  
\_main:  
&nbsp;&nbsp;pushq %rbp  
&nbsp;&nbsp;movq %rsp, %rbp  
&nbsp;&nbsp;movl $128, %edi  
&nbsp;&nbsp;xorl %esi, %esi  
&nbsp;&nbsp;callq \_swift\_rt\_swift\_slowAlloc ; a.k.a. ‘malloc'  
&nbsp;&nbsp;movq %rax, \_\_Tv4main3ptrSv(%rip)  
&nbsp;&nbsp;movl $128, %esi  
&nbsp;&nbsp;xorl %edx, %edx  
&nbsp;&nbsp;movq %rax, %rdi  
&nbsp;&nbsp;callq \_swift\_rt\_swift\_slowDealloc ; a.k.a ‘free'  
&nbsp;&nbsp;xorl %eax, %eax  
&nbsp;&nbsp;popq %rbp  
&nbsp;&nbsp;retq

Would be cool to do one day, though.

- Karl

> **···**
>
> > On 18 Apr 2017, at 00:29, Karl Wagner \<karl.swift@springsup.com\> wrote:
> > 
> > > On 17 Apr 2017, at 23:18, Michael Ilseman via swift-evolution \<swift-evolution@swift.org \<mailto:swift-evolution@swift.org\>\> wrote:
> > > 
> > > This is the best approach that I’m aware of. It does bake in an ABI assumption that the tuple layout will be contiguous and strided/addressable. Monitor [[SR-3726] Define layout algorithm for tuples · Issue #46311 · apple/swift · GitHub](https://bugs.swift.org/browse/SR-3726) for changes here. Note that you can also a little more “pure” in a sense if you construct an UnsafeBufferPointer from your UnsafeRawPointer and operate on that. Currently, the compiler does not always elide the copy in the getter, see [[SR-4581] Optimizer doesn't elide copy · Issue #47158 · apple/swift · GitHub](https://bugs.swift.org/browse/SR-4581)
> > 
> > Will the compiler ever optimise an UBP allocation on to the stack? For example, I’ve written plenty of code such as:
> > 
> > let ptr = UnsafeRawBufferPointer.allocate(count: 128)  
> > defer { ptr.deallocate(count: 128) }
> > 
> > ...when interfacing with C APIs. Which is basically the definition of a stack allocation. That would perhaps be the “swiftier” way to do it; to let the compiler determine how to allocate the memory based on what it knows about its expected lifetime.

---

<div class="post-metadata">

**Author:** ![JetForMe](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/jetforme/32/482_2.png) [@JetForMe](https://forums.swift.org/u/JetForMe)\
**Post date:** [December 11, 2018, 1:33am UTC](https://forums.swift.org/t/swift-needs-fixed-size-array/5685/12 "2018-12-11T01:33:46Z")

</div>

Has anything come of this? Associated JIRA tickets haven't had any activity in over a year:

> <https://github.com/apple/swift/issues/47119>
>
> | | |
> |------------------|-----------------|…
> |Previous ID | SR-4542 |
> |Radar | None |
> |Original Reporter | smartgo (JIRA User) |
> |Type | Bug |
> 
> 
> Attachment: \[Download\](https://user-images.githubusercontent.com/2727770/164962018-be10cdaf-491e-4d43-9d8c-ffe42eb06c59.gz)
> 
>       
> \<details\>
> \<summary\>Environment\</summary\>
> 
> Xcode 8.3 (8E162), macOS 10.12.4 (16E195)
> 
> 
> \</details\>
> 
> \<details\>
> \<summary\>Additional Detail from JIRA\</summary\>
> 
> | | |
> |------------------|-----------------|
> |Votes | 1 |
> |Component/s | Compiler |
> |Labels | Bug, LanguageFeatureRequest |
> |Assignee | None |
> |Priority | Medium |
> 
>    
> 
> md5: 713abe4534ab19d75f4e6cbdf923fbeb
> 
> \</details\>
> 
> 
> 
> 
> \*\*relates to\*\*:  
> \* \[SR-1956\](https://bugs.swift.org/browse/SR-1956) \`withUnsafePointer\` shouldn't take its argument as \`inout\`  
> 
> 
> \*\*Issue Description:\*\*
> 
> 
> Summary: When bridging to a struct imported from C, getting the address of an  
> object means the method needs to be mutable, which it should not be.
> 
> //------------------------------------------------------------------------------  
> // Bitset: A set of points on a Go board as a C struct.
> 
> const int NumWords = 6;
> 
> struct Bitset {  
> uint64\_t bits\\\[NumWords\\\];  
> };
> 
> //------------------------------------------------------------------------------  
> // PointSet: A set of points on a Go board as a Swift struct. Would like to use  
> // a Swift array, but that incurs a heap allocation we can't afford.
> 
> struct PointSet {
> 
> var bits = Bitset()
> 
> mutating func include(\\\_ p: Int) {  
> setBitRaw(&bits, bit: p)  
> }
> 
> // BUG: This method should not be 'mutating', but needs to be because can't  
> // pass the address of bits to UnsafeRawPointer without using &, which  
> // tells the compiler that 'bits' get mutated. This 'mutating' then  
> // causes ripple effects throughout the client code.  
> mutating func contains(\\\_ p: Int) -\\\> Bool {  
> return testBitRaw(&bits, bit: p)  
> }  
> }
> 
> //------------------------------------------------------------------------------  
> // bit functions
> 
> typealias Word = UInt64  
> let BitsPerWord = 64  
> let Log2of64 = 6  
> let NumWords = 6
> 
> func wordWithBit(\\\_ bit: Int) -\\\> Int {  
> return Int(bit \\\>\\\> Log2of64)  
> }
> 
> func bitInWord(\\\_ bit: Int) -\\\> Word {  
> return Word(bit) & Word(BitsPerWord-1)  
> }
> 
> func setBitRaw(\\\_ pointer: UnsafeMutableRawPointer, bit: Int) {  
> let a = pointer.bindMemory(to: Word.self, capacity: NumWords)  
> a\\\[wordWithBit(bit)\\\] \\|= (1 \\\<\\\< bitInWord(bit))  
> }
> 
> func testBitRaw(\\\_ pointer: UnsafeRawPointer, bit: Int) -\\\> Bool {  
> let a = pointer.bindMemory(to: Word.self, capacity: NumWords)  
> return (a\\\[wordWithBit(bit)\\\] & (1 \\\<\\\< bitInWord(bit))) != 0  
> }
> 
> See the attached sample project. Would love to find out that there's a less ugly way to do this (without losing performance).

> <https://github.com/apple/swift/issues/47226>
>
> | | |
> |------------------|-----------------|…
> |Previous ID | SR-4649 |
> |Radar | None |
> |Original Reporter | smartgo (JIRA User) |
> |Type | Improvement |
> 
> 
> Attachment: \[Download\](https://user-images.githubusercontent.com/2727770/164962044-0d187b55-9af4-4bf6-b263-de2f87ab1aab.gz)
> 
>       
> \<details\>
> \<summary\>Additional Detail from JIRA\</summary\>
> 
> | | |
> |------------------|-----------------|
> |Votes | 1 |
> |Component/s | Compiler |
> |Labels | Improvement, LanguageFeatureRequest |
> |Assignee | None |
> |Priority | Medium |
> 
>    
> 
> md5: 0988f63ad6ccc74f00f9fa5fc89b1c7a
> 
> \</details\>
> 
> 
> 
> 
> \*\*relates to\*\*:  
> \* \[SR-1956\](https://bugs.swift.org/browse/SR-1956) \`withUnsafePointer\` shouldn't take its argument as \`inout\`  
> \* \[SR-4929\](https://bugs.swift.org/browse/SR-4929) Support non-inout homogeneous tuple argument conversion to UnsafePointer\<Element\>  
> 
> 
> \*\*Issue Description:\*\*
> 
> 
> The following code shows the inconsistency in passing values to UnsafeRawPointer:
> 
> func get(\\\_ pointer: UnsafeRawPointer, at index: Int) -\\\> Int {  
> let a = pointer.bindMemory(to: Int.self, capacity: 6)  
> return a\\\[index\\\]  
> }
> 
> var varArray = \\\[Int\\\](repeating: 0, count: 6)  
> var varTuple = (0, 0, 0, 0, 0, 0)
> 
> let letArray = \\\[Int\\\](repeating: 0, count: 6)  
> let letTuple = (0, 0, 0, 0, 0, 0)
> 
> // Array can be passed directly, automatically takes address.  
> \\\_ = get(varArray, at: 2) // okay  
> \\\_ = get(letArray, at: 2) // okay
> 
> // When explicitly taking address, can only pass mutable variables.  
> \\\_ = get(&varArray, at: 2) // okay, but seems inconsistent  
> \\\_ = get(&letArray, at: 2) // fails: & not allowed
> 
> // Passing tuple instead of array fails.  
> \\\_ = get(varTuple, at: 2) // fails (wrong type)  
> \\\_ = get(letTuple, at: 2) // fails (wrong type)
> 
> // Adding & to pass a tuple only works for mutable values. Having to  
> // pass the address using & means that any methods calling this must  
> // be mutating, even though they don't mutate.  
> \\\_ = get(&varTuple, at: 2) // okay, but forces mutating  
> \\\_ = get(&letTuple, at: 2) // fails: cannot pass immutable value
> 
> Getting an UnsafeRawPointer should not require use of &, as that forces all code calling it to be mutating. Having a special case for array also doesn't make sense, as the idea of UnsafeRawPointer is that we're interpreting that memory content as whatever we want. This needs to be fixed. This is related to SR-4542, as a C array is imported as tuples, and thus read-only access is not possible without being mutating.
> 
> Proposal:
> 
> \- Never require & when passing value to UnsafeRawPointer.
> 
> \- Always require & when passing value to UnsafeMutableRawPointer.
