The attribute @inline(__always)
forces the compiler to inline a particular function. How is code provided by external libraries inlined in one's project? Does the compiler actually copy code segments from the library's executable?
As far as I'm aware, @inline(__always)
means that the function (or similar) is always inlined, no matter what. That means that its symbols are exposed in the compiled module so they can be inlined by projects consuming that module. Hence the "always".
This is largely an undocumented attribute, with the only official references I can find being in some stdlib devs' internal documentation, not even describing its behavior directly. The best unofficial documentation I can find is Vandad Nahavandipoor's disassembly-confirmed investigation into its behavior, which doesn't attempt to confirm the cross-module use case you are concerned with.
In Swift 4.2, @inlinable
and @usableFromInline
were introduced to finish this story.
@inline(__always)
forces functions (et al) to be inlined every time no matter where they're declared or used@inlinable
allows functions (et al) in a module to be inlined into calling code in that module, or calling code using that module, if the compiler deems it necessary@usableFromInline
allows functions (et al) internal to a module to be inlined into @inlinable
calling code that's also in that module, if the compiler deems it necessary. Unlike @inlinable
, these must be internal
; they cannot be public
inlinable
Apply this attribute to a function, method, computed property, subscript, convenience initializer, or deinitializer declaration to expose that declaration’s implementation as part of the module’s public interface. The compiler is allowed to replace calls to an inlinable symbol with a copy of the symbol’s implementation at the call site.
Inlinable code can interact with
public
symbols declared in any module, and it can interact with internal symbols declared in the same module that are marked with theusableFromInline
attribute. Inlinable code can’t interact withprivate
orfileprivate
symbols.This attribute can’t be applied to declarations that are nested inside functions or to
fileprivate
orprivate
declarations. Functions and closures that are defined inside an inlinable function are implicitly inlinable, even though they can’t be marked with this attribute.
usableFromInline
Apply this attribute to a function, method, computed property, subscript, initializer, or deinitializer declaration to allow that symbol to be used in inlinable code that’s defined in the same module as the declaration. The declaration must have the internal access level modifier. A structure or class marked
usableFromInline
can use only types that are public orusableFromInline
for its properties. An enumeration markedusableFromInline
can use only types that are public orusableFromInline
for the raw values and associated values of its cases.Like the
public
access level modifier, this attribute exposes the declaration as part of the module’s public interface. Unlikepublic
, the compiler doesn’t allow declarations marked withusableFromInline
to be referenced by name in code outside the module, even though the declaration’s symbol is exported. However, code outside the module might still be able to interact with the declaration’s symbol by using runtime behavior.Declarations marked with the
inlinable
attribute are implicitly usable frominlinable
code. Although eitherinlinable
orusableFromInline
can be applied tointernal
declarations, applying both attributes is an error.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With