<html><head><meta http-equiv="content-type" content="text/html; charset=utf-8"></head><body dir="auto"><div></div><div style="direction: inherit;">No problem, I'll put it on the back burner for the time being.&nbsp;</div><div style="direction: inherit;"><br></div><div style="direction: inherit;">Russ</div><div><br>On Aug 19, 2016, at 12:50 PM, Joe Groff &lt;<a href="mailto:jgroff@apple.com">jgroff@apple.com</a>&gt; wrote:<br><br></div><blockquote type="cite"><div><span></span><br><blockquote type="cite"><span>On Aug 17, 2016, at 11:28 AM, Russ Bishop via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a>&gt; wrote:</span><br></blockquote><blockquote type="cite"><span></span><br></blockquote><blockquote type="cite"><span>I wanted to gauge the interest in supporting explicit struct layout and alignment.</span><br></blockquote><blockquote type="cite"><span></span><br></blockquote><blockquote type="cite"><span>The general idea would be to support attributes to create packed structs and set alignment. It will be critical for certain kinds of interop and systems programming in pure Swift. I don’t know about you but I want to write a kernel module in Swift someday :) I’m bringing it up because it probably affects ABI stability and resilience and so meets the requirements for Swift 4 phase 1.</span><br></blockquote><blockquote type="cite"><span></span><br></blockquote><blockquote type="cite"><span>Hopefully this could be a jumping-off point for further discussion. If the core team doesn’t think this affects ABI stability then we can postpone discussing it until Swift 4 phase 1 wraps up.</span><br></blockquote><blockquote type="cite"><span></span><br></blockquote><blockquote type="cite"><span></span><br></blockquote><blockquote type="cite"><span>@layout(style: auto, alignment: natural)</span><br></blockquote><blockquote type="cite"><span></span><br></blockquote><blockquote type="cite"><span>enum LayoutStyle {</span><br></blockquote><blockquote type="cite"><span> &nbsp;&nbsp;&nbsp;/// Compiler is free to order the fields as it likes</span><br></blockquote><blockquote type="cite"><span> &nbsp;&nbsp;&nbsp;case automatic</span><br></blockquote><blockquote type="cite"><span> &nbsp;&nbsp;&nbsp;/// Places a struct's members in source order</span><br></blockquote><blockquote type="cite"><span> &nbsp;&nbsp;&nbsp;case sequential</span><br></blockquote><blockquote type="cite"><span> &nbsp;&nbsp;&nbsp;/// Requires each member to have an @order attribute</span><br></blockquote><blockquote type="cite"><span> &nbsp;&nbsp;&nbsp;case ordered</span><br></blockquote><blockquote type="cite"><span> &nbsp;&nbsp;&nbsp;/// Requires each member to have an @offset attribute</span><br></blockquote><blockquote type="cite"><span> &nbsp;&nbsp;&nbsp;case explicit</span><br></blockquote><blockquote type="cite"><span>}</span><br></blockquote><blockquote type="cite"><span></span><br></blockquote><blockquote type="cite"><span>Only structs with certain @layout attributes would be exportable to non-Swift languages (assuming such support is added at some point). A struct defined with ordered or explicit layout and as resilient could possibly avoid indirect access to members since the ABI contract guarantees the location of each member.</span><br></blockquote><blockquote type="cite"><span></span><br></blockquote><blockquote type="cite"><span></span><br></blockquote><blockquote type="cite"><span>enum Alignment {</span><br></blockquote><blockquote type="cite"><span> &nbsp;&nbsp;&nbsp;/// Compiler decides</span><br></blockquote><blockquote type="cite"><span> &nbsp;&nbsp;&nbsp;case natural</span><br></blockquote><blockquote type="cite"><span> &nbsp;&nbsp;&nbsp;/// Align as if the natural alignment were specified bytes</span><br></blockquote><blockquote type="cite"><span> &nbsp;&nbsp;&nbsp;case bytes(Int)</span><br></blockquote><blockquote type="cite"><span>}</span><br></blockquote><blockquote type="cite"><span></span><br></blockquote><blockquote type="cite"><span></span><br></blockquote><blockquote type="cite"><span></span><br></blockquote><blockquote type="cite"><span>@order(&lt;int&gt;)</span><br></blockquote><blockquote type="cite"><span></span><br></blockquote><blockquote type="cite"><span>Specifies the order of the member in memory. Order must start at zero and increase monotonically without gaps. This makes accidental changes to the ordering errors.</span><br></blockquote><blockquote type="cite"><span></span><br></blockquote><blockquote type="cite"><span></span><br></blockquote><blockquote type="cite"><span></span><br></blockquote><blockquote type="cite"><span>@offset(&lt;int&gt;)</span><br></blockquote><blockquote type="cite"><span></span><br></blockquote><blockquote type="cite"><span>Specifies the offset from the start of the struct where this member should be placed. The size of the struct becomes the highest offset plus the size of the member with that offset.</span><br></blockquote><blockquote type="cite"><span></span><br></blockquote><blockquote type="cite"><span>It is an open question whether overlapping alignment should be allowed. If it is allowed I’d propose that for any set of members overlapping all of the members must be entirely contained within the largest overlapping member (I’m thinking of C-style unions when the struct format is imposed by something outside your control).</span><br></blockquote><blockquote type="cite"><span></span><br></blockquote><blockquote type="cite"><span></span><br></blockquote><blockquote type="cite"><span></span><br></blockquote><blockquote type="cite"><span>Thoughts?</span><br></blockquote><span></span><br><span>Property behaviors could conceivably get you at least some of the way here. You could do something like this:</span><br><span></span><br><span>protocol ManualLayout {</span><br><span> &nbsp;associatedtype Storage</span><br><span> &nbsp;var storage: Storage</span><br><span>}</span><br><span></span><br><span>struct Foo: ManualLayout {</span><br><span> &nbsp;var storage: [4 x Int32] // give me 16 bytes of 32-bit-aligned storage</span><br><span></span><br><span> &nbsp;var [offset(0)] foo: Int32</span><br><span> &nbsp;var [offset(5)] bar: Int32</span><br><span> &nbsp;var [offset(10)] bas: Int32</span><br><span>}</span><br><span></span><br><span>-Joe</span></div></blockquote></body></html>