Value Categories¶
Slang has two primary value categories:
An L-value has underlying mutable storage. Hence, an L-value can be on the left side of an assignment, and it can be used as an argument to an
out/inoutfunction parameter.An R-value is a temporary or otherwise immutable value. It can only be used in contexts where a pure value is adequate. It cannot be used as an argument to an
out/inoutfunction parameter. An R-value is typically a result of a computation, a value passed as a copy, or a result of a function invocation.
The following expressions are L-values:
Access to a mutable variable
Access to an
out/inout/__refparameterAccess to an
inparameter that has been declared using the traditional variable declaration (C-style)Note: the argument is still passed by value copy
Pointer dereference when the pointer access type is
Access.ReadWriteAccess to a reference
Access to a property when it has a setter accessor and the base is an L-value
Applying a subscript operator when both:
The base is an L-value
The subscript operator is built-in, OR it is user-defined with a setter accessor
Access to
thisin a mutating contextReturn value for a non-copyable return type
Access to a member when the base is an L-value
Swizzle expression when both:
The base is an L-value
The swizzle expression has no duplicate components
Cast of an L-value object to a conforming type
Access to an interface-typed mutable object (dynamic dispatch)
Implicit casts that preserve the L-value category (e.g. for
inout/outparameters)
Other expressions are R-value expressions.
Slang expressions are also categorized as addressable and non-addressable:
An addressable value has underlying storage that may be mutable, read-only, or immutable. Its address may be requested with
__getAddress()on targets that support pointers.A non-addressable value does not have underlying storage, and in that sense, it is a true temporary value.
📝 Remark: Pointer support in Slang is currently experimental. The details are subject to change.
Where L-values Are Required¶
L-values are required in the following places:
Argument to an
out/inout/__refparameterLeft-hand-side operand of an assignment operator, including compound assignment operators
Operand to pre-increment, pre-decrement, post-increment, and post-decrement operators
Object receiving a
[mutating]or[ref]member function callObject receiving a property setter call or a user-defined subscript operator setter call, unless the setter has been explicitly marked as
[nonmutating].