From 4a3a4a9d0266f1c2439ece51c2275fe57100824f Mon Sep 17 00:00:00 2001 From: Chris Bieneman Date: Tue, 24 Jun 2025 20:00:36 -0500 Subject: [PATCH] [0005] Add detailed design This adds a detailed design including draft language spec wording for the strict initializer lists proposal. --- proposals/0005-strict-initializer-lists.md | 80 ++++++++++++++++++++++ 1 file changed, 80 insertions(+) diff --git a/proposals/0005-strict-initializer-lists.md b/proposals/0005-strict-initializer-lists.md index 2065e023..816f6a3d 100644 --- a/proposals/0005-strict-initializer-lists.md +++ b/proposals/0005-strict-initializer-lists.md @@ -67,6 +67,86 @@ Fix-It will be backwards compatible to prior HLSL versions. New code that takes advantage of C & C++'s zero-initialization behavior, will not be backwards compatible to older HLSL versions. +## Detailed Design + +HLSL 202y shall adopt specification language aligned with the [ISO C++ +specification (ISO/IEC +14882:2011)](https://timsong-cpp.github.io/cppwp/n3337/dcl.init). + +The language in the next subsection will replace the **Decl.Init.Agg** section +of the HLSL specification. + +### Specification Language + +An _aggregate_ is a vector, matrix, array, or class which contains +* no user-declared or inherited constructors +* no non-public non-static data members, and +* no non-public base classes + +The subobjects of an aggregate have a defined _subobject order_. For vectors and +arrays the order is increasing subscript order. For matrices it is increasing +subscript order with the subscript nesting such that in the notation +`Mat[M][N]`, the ordering is `Mat[0][0]...Mat[0][N]... Mat[M][0]...Mat[M][N]`. +For classes the order is recursively the order of the base class, followed by +member subobjects in declaration order. Anonymous bitfields are not included in +the subobject ordering. + +When initialized by an initializer list the elements of the initializer list are +initializers for the members of the aggregate in subobject order. Each member is +copy-initialized from the corresponding initializer-clause. If the +initializer-clause is an expression which requires a narrowing conversion to +convert to the subobject type, the program is ill-formed. + +An aggregate that is a class can also be initialized by a single expression not +enclosed in braces. + +An array of unknown size may be initialized by a brace enclosed +initializer-list. For arrays of unknown size the initializer list shall contain +`n` initializers where `n > 0` and will produce an array containing `n` +elements. + +If an initializer-list contains more initializer-clauses than the number of +subbjects being initialized, the program is ill-formed. + +If an initializer-list contains fewer initializer-clauses than the number of +subobjects being initialized, each member not explicitly initialized shall be +initialized as if by an empty initializer list. + +If an aggregate class contains a subobject member that has no members in its +subobject order, the initializer-clause for the empty subobject shall not be +omitted from an initializer list for the containing class unless the +initializer-caluses for all following members of the class are also omitted. + +An initializer-list that is part of a braced-init-list may elide braces for +initializing subobjects. If braces are elided, a number of initializer-clauses +equal to the subobject's number of elements initializes the subobject. If braces +are present, it forms a braced-init-list which initializes the subobject +following the rules of this section. + +A multi-dimensional array may be initialized using a single braced-initializer +list or with nested initializer lists. When initializing with a single +braced-initializer the order of initialization matches the memory layout. + +```hlsl +int x[2][2] = {1, 2, 3, 4}; // [0][0] = 1, [0][1] = 2, + // [1][0] = 3,[1][1] = 4 +int y[3][2] = {{1,2}, {3}, {4}}; // [0][0] = 1, [0][1] = 2, + // [1][0] = 3, [1][1] = 0, + // [2][0] = 4, [2][1] = 0 +``` + +Element initialization behaves as if an assignment-expression is evaluated +from the initializer-clause to the initialized member. All implicit conversions +are applied as appropriate to convert the initializer to the member type. If the +assignment-expression is ill-formed and the element is a subobject, brace +elision is assumed and an assignment-expression is evaluated as if initializing +the first element of the subobject. If both assignment-expressions are +ill-formed the program is ill-formed. + +When a union is initialized with an initializer-list, the initializer-list will +contain only one initializer-clause which will initialize the first non-static +data member of the union. + ## Unanswered Questions ### Should we support initialization constructors (i.e. `uint4 i4{}`)?