Standard Conversions[Conv]

4 Standard Conversions[Conv]

hlsl inherits standard conversions similar to isoCPP. This chapter enumerates the full set of conversions. A standard conversion sequence is a sequence of standard conversions in the following order:

  1. Zero or one conversion of either lvalue-to-rvalue, or array-to-pointer.

  2. Zero or one conversion of either integral conversion, floating point conversion, floating point-integral conversion, or boolean conversion, derived-to-base-lvalue, or flat conversion1.

  3. Zero or one conversion of scalar-vector splat, or vector/matrix truncation. 2.

  4. Zero or one qualification conversion.

Standard conversion sequences are applied to expressions, if necessary, to convert it to a required destination type.

4.1 Lvalue-to-rvalue conversion[Conv.lval]

A glvalue of a non-function type T can be converted to a prvalue. The program is ill-formed if T is an incomplete type. If the glvalue refers to an object that is not of type T and is not an object of a type derived from T, the program is ill-formed. If the glvalue refers to an object that is uninitialized, the behavior is undefined. Otherwise the prvalue is of type T.

If the glvalue refers to an array of type T, the prvalue will refer to a copy of the array, not memory referred to by the glvalue.

4.2 Array-to-pointer conversion[Conv.array]

An lvalue or rvalue of type T[] (unsized array), can be converted to a prvalue of type pointer to T34.

4.3 Integral promotion[Conv.ipromote]

An integral promotion is a conversion of:

  • a glvalue of integer type other than bool to a cxvalue of integer type of higher conversion rank, or

  • a conversion of a prvalue of integer type other than bool to a prvalue of integer type of higher conversion rank, or

  • a conversion of a glvalue of type bool to a cxvalue of integer type, or

  • a conversion of a prvalue of type bool to a prvalue of integer type.

Integer conversion ranks are defined in section 4.16.1.

A conversion is only a promotion if the destination type can represent all of the values of the source type.

4.4 Floating point promotion[Conv.fppromote]

A glvalue of a floating point type can be converted to a cxvalue of a floating point type of higher conversion rank, or a prvalue of a floating point type can be converted to a prvalue of a floating point type of higher conversion rank.

Floating point conversion ranks are defined in section [Conf.rank.float].

4.5 Integral conversion[Conv.iconv]

A glvalue of an integer type can be converted to a cxvalue of any other non-enumeration integer type. A prvalue of an integer type can be converted to a prvalue of any other integer type.

If the destination type is unsigned, integer conversion maintains the bit pattern of the source value in the destination type truncating or extending the value to the destination type.

If the destination type is signed, the value is unchanged if the destination type can represent the source value. If the destination type cannot represent the source value, the result is implementation-defined.

If the source type is bool, the values true and false are converted to one and zero respectively.

4.6 Floating point conversion[Conv.fconv]

A glvalue of a floating point type can be converted to a cxvalue of any other floating point type. A prvalue of a floating point type can be converted to a prvalue of any other floating point type.

If the source value can be exactly represented in the destination type, the conversion produces the exact representation of the source value. If the source value cannot be exactly represented, the conversion to a best-approximation of the source value is implementation defined.

4.7 Floating point-integral conversion[Conv.fpint]

A glvalue of floating point type can be converted to a cxvalue of integer type. A prvalue of floating point type can be converted to a prvalue of integer type. Conversion of floating point values to integer values truncates by discarding the fractional value. The behavior is undefined if the truncated value cannot be represented in the destination type.

A glvalue of integer type can be converted to a cxvalue of floating point type. A prvalue of integer type can be converted to a prvalue of floating point type. If the destination type can exactly represent the source value, the result is the exact value. If the destination type cannot exactly represent the source value, the conversion to a best-approximation of the source value is implementation defined.

4.8 Boolean conversion[Conv.bool]

A glvalue of arithmetic type can be converted to a cxvalue of boolean type. A prvalue of arithmetic or unscoped enumeration type can be converted to a prvalue of boolean type. A zero value is converted to false; all other values are converted to true.

4.9 Elementwise conversion[Conv.flat]

For a given aggregate A, there is a flattened order of subojects, A, as described in section 7.4.1. A prvalue of A, can be elementwise converted to a prvalue of an aggregate B, whose flattened form is B, if the following conditions are true:

  • The length of A, N, is greater than or equal to the length of B, M.

  • For every index I from to M-1, there exists an implicit conversion from A[I] to B[I].

A glvalue of type T[N] can be converted to a cxvalue of type T.

A glvalue of type T[N] can be converted to a cxvalue of type T[M], if N is greater than M.

A glvalue of type T[N] can be converted to a cxvalue of type vector<T,M>, if N is greater than or equal to M.

A glvalue of type vector<T,N> can be converted to a cxvalue of type T[M], if N is greater than or equal to M.

4.10 Vector splat conversion[Conv.vsplat]

A glvalue of type T can be converted to a cxvalue of type vector<T,x> or a prvalue of type T can be converted to a prvalue of type vector<T,x>. The destination value is the source value replicated into each element of the destination.

A prvalue of type vector<T,1> can be converted to a prvalue of type vector<T,x>. The destination value is the value in the source vector replicated into each element of the destination.

4.11 Matrix splat conversion[Conv.msplat]

A glvalue of type T can be converted to a cxvalue of type matrix<T,x,y> or a prvalue of type T can be converted to a prvalue of type matrix<T,x,y>. The destination value is the source value replicated into each element of the destination.

4.12 Array and Class splat conversion[Conv.asplat]

A prvalue of type T can be converted to a prvalue of type struct S, if there are valid conversions from T to each U in flattened S, see section [Decl.init.Agg] for description of a flattened ordering. The destination value is the source value T replicated into each element of the flattened S.

A prvalue of type vector<T,1> can be converted to a prvalue of type struct S, if there are valid conversions from T to each U in flattened S. The destination value is the value in the source vector replicated into each element of the flattened S.

A prvalue of type T can be converted to a prvalue of type U[N], if there are valid conversions from T to each V in flattened U. The destination value is the source value T replicated into each element of the flattened U[N].

A prvalue of type vector<T,1> can be converted to a prvalue of type U[N], if there are valid conversions from T to each V in flattened U. The destination value is the value in the source vector replicated into each element of the flattened U[N].

4.13 Vector and matrix truncation conversion[Conv.vtrunc]

A prvalue of type vector<T,x> can be converted to a prvalue of type:

  • vector<T,y> only if y < x, or

  • T

The resulting value of vector truncation is comprised of elements [0..y), dropping elements [y..x).

A prvalue of type matrix<T,x,y> can be converted to a prvalue of type:

  • matrix<T,z,w> only if x ≥ z and y ≥ w,

  • vector<T,z> only if x ≥ z, or

  • T.

Matrix truncation is performed on each row and column dimension separately. The resulting value is comprised of vectors [0..z) which are each separately comprised of elements [0..w). Trailing vectors and elements are dropped.

Reducing the dimension of a vector to one (vector<T,1>), can produce either a single element vector or a scalar of type T. Reducing the rows of a matrix to one (matrix<T,x,1>), can produce either a single row matrix, a vector of type vector<T,x>, or a scalar of type T.

4.14 Component-wise conversions[Conv.cwise]

A glvalue of type vector<T,x> can be converted to a cxvalue of type vector<V,x>, or a prvalue of type vector<T,x> can be converted to a prvalue of type vector<V,x>. The source value is converted by performing the appropriate conversion of each element of type T to an element of type V following the rules for standard conversions in chapter 4.

A glvalue of type matrix<T,x,y> can be converted to a cxvalue of type matrix<V,x,y>, or a prvalue of type matrix<T,x,y> can be converted to a prvalue of type matrix<V,x,y>. The source value is converted by performing the appropriate conversion of each element of type T to an element of type V following the rules for standard conversions in chapter 4.

4.15 Qualification conversion[Conv.qual]

A prvalue of type "cv1 T" can be converted to a prvalue of type "cv2 T" if type "cv2 T" is more cv-qualified than "cv1 T".

4.16 Conversion Rank[Conv.rank]

Every integer and floating point type have defined conversion ranks. These conversion ranks are used to differentiate between promotions and other conversions (see: [Conv.iprom] and [Conv.fpprom]).

4.16.1 Integer Conversion Rank[Conv.rank.int]

  • No two signed integer types shall have the same conversion rank even if they have the same representation.

  • The rank of a signed integer type shall be greater than the rank of any signed integer type with a smaller size.

  • The rank of any unsigned integer type shall equal the rank of the corresponding signed integer type.

  • The rank of bool shall be less than the rank of all other standard integer types.

  • The rank of a minimum precision integer type shall be less than the rank of any other minimum precision integer type with a larger minimum value representation size.

  • The rank of a minimum precision integer type shall be less than the rank of all standard integer types.

  • For all integer types T1, T2, and T3: if T1 has greater rank than T2 and T2 has greater rank than T3, then T1 shall have greater rank than T3.

4.16.2 Floating Point Conversion Rank[Conv.rank.float]

  • The rank half shall be greater than the rank of min16float.

  • The rank float shall be greater than the rank of half.

  • The rank double shall be greater than the rank of float.

  • For all floating point types T1, T2, and T3: if T1 has greater rank than T2 and T2 has greater rank than T3, then T1 shall have greater rank than T3.