diff --git a/proposals/0005-strict-initializer-lists.md b/proposals/0005-strict-initializer-lists.md index 2065e023..58f757c9 100644 --- a/proposals/0005-strict-initializer-lists.md +++ b/proposals/0005-strict-initializer-lists.md @@ -67,6 +67,125 @@ 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 does not contain +* user-declared or inherited constructors +* non-public non-static data members, or +* non-public base classes + +For the purposes of aggregate initialization, anonymous bit-fields are not +considered members of an object. + +When initialized by an initializer list, the elements of the initializer list +are initializers for the members of the aggregate in subscript or member 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 a one-dimensional array containing `n` +elements. + +If an initializer-list contains more initializer-clauses than the number of +subobjects 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 non-static data +members, 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. + +```hlsl +struct Empty {}; + +struct Space { + int Stars; + Empty E; + double Size; +}; + +Space A = {}; // Zero-initializes all members. +Space B = {1}; // Initializes Stars to 1 then zero-initializes remaining + // fields. +Space C = {1, 4}; // Ill-formed, cannot initialize Empty from 4, and cannot + // omit the empty initializer. +Space D = {1, {}, 4}; // Initializes Stars to 1 and Size to 4. +``` + + +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. + +```hlsl +RWBuffer Buf; + +struct ResourceRef { + RWBuffer B; + int Offset; +}; + +struct A { + int X; + RWBuffer B; +}; + +struct B { + A S; + int Y; +}; + +A T = 1; // This is ill-formed, cannot initialize A from int. + +B U = {1,B,3}; // This is fine, brace elision is assumed because A cannot be + // initialized from int +B V = {1,2,3}; // This is ill-formed, cannot initialize RWBuffer from int. + +``` + +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{}`)?