Ecma TC57 - HLSL

0010 - Modern C++ Features

StatusRefinement
Author
  • Issues:
    • auto: #24
    • decltype: #82
    • constexpr: #21 #74
    • variadic templates: #21
    • static assert: #33
    • simplified nested namespace: #68

Implementation Status

DXCClang
C++11 template closing >>CompleteComplete
variadic templatesNot StartedComplete
variable templatesNot StartedNot Started
auto keywordCompleteComplete
decltypeNot StartedComplete
Return type deduction for normal functionsNot StartedNot Started
constexprPrototypeComplete
static_assertPrototypeComplete

Introduction

In DXC HLSL is a set of feature extensions on top of a subset of C++98. C++98 is now over 20 years old and most modern C++ users have adopted newer language constructs. This proposal suggests integrating high-impact modern C++ features that should be low-cost to implement.

Motivation

HLSL’s C++ base is over a decade old. Modern C++ features have been frequently requested additions for HLSL. Features introduced in C++11 and C++14 have been in use for over a decade and are widely adopted. C++17 is nearly a decade old now as well, and also has many widely adopted features. Conversely C++98 has some oddities that are unusual and unexpected to developers who may have started their career after modern C++ was widely adopted.

Proposed solution

This proposal introduces a small number of targeted modern C++ features for HLSL which improve and extend the capabilities of HLSL 2021 while reducing friction bridging between HLSL and C++.

Modern Template

C++11 and C++14 introduced several valuable extensions to C++’s template support which HLSL will adopt.

HLSL will adopt the template parsing rules allowing closing template brackets (>>) to be adjacent without whitespace separating the tokens. This feature was adopted to C++11 in the paper Right Angle Brakcets (n1757).

HLSL will adopt C++’s variadic templates. This feature was adopted to C++11 in the paper Proposed Wording for Variadic Templates (n2242).

HLSL will adopt C++’s variable templates. This feature was adopted to C++14 in the paper Variable Templates (n3651).

Collectively these features allow modernization of C++ template meta-programming patterns to align mostly with modern C++ in terms of expressiveness and capabilities.

Type deduction with auto and decltype

HLSL will adopt C++’s auto and decltype keywords. These features were adopted to C++11 in the paper Decltype and auto (n1607).

HLSL will also adopt C++’s simplifications of return type deduction for functions. This feature was adpoted to C++14 in the paper Return type deduction for normal functions (n3638).

These features enable additional patterns of meta-programming building off C++ templates and allowing for more concise readable code.

Compile-time evaluation

C++11 introduced a set of features which subsequent versions have built on to enable compile-time evaluation of portions of programs and compile-time verification.

HLSL will adopt the constexpr keyword and the associated behaviors introduced to C++11 in the paper Generalized constant expressions (n2235). This feature will not support the full breadth of C++14’s constexpr function capabilities, and will be limited to just the C++11 functionality.

To allow using generalized constant expressions for compile-time correctness testing HLSL will adopt the static_assert feature adopted to C++11 in the paper Proposal to Add Static Assertions to the Core Language (n1720).

Additionally we adopt the additions to static_assert adopted to C++17 in the paper Extending static_assert (n3928).

These features enable robust compile-time expressions and testability of assumptions which will enable developers to detect errors earlier and write more maintainable code without hard-coded assumptions.

Appendix A: Listing of C++ Features Considered

C++11

HLSL should integrate the following C++11 features (Source):

  • auto - Implemented in both DXC and Clang
  • decltype
  • constexpr
  • variadic templates
  • Static assert
  • Template parsing rules (no required space in >>)

C++11 Excluded Features

  • Range-based for loops (grammar ambiguity with HLSL annotations)
  • C++11 attributes (will be a separate larger proposal)
  • Defaulted and deleted functions (requires constructors)
  • C++ list initialization (requires revamping HLSL initialization)
  • type aliases (already in HLSL 2021)
  • alignof and alignas (requires target bytecode changes)
  • Lambda expressions (will require a separate larger proposal due to type system changes)
  • C++11 scoped enumerations (will be a separate proposal)
  • user-defined literals (deferred)
    • User-defined literals prompted numerous defect reports to WG21, addressing those is out-of-scope for HLSL 202x.

C++14

C++14 features that we could consider (Source):

  • variable templates
  • relaxed restrictions on constexpr functions
  • binary literals
  • digit separators
  • return type deduction for functions

C++14 Excluded features

  • generic lambdas (requires lambdas)
  • lambda init-capture (requires lambdas)
  • new/delete elision (requires new/delete)
  • aggregate classes with default non-static member initializers (requires constructors)

C++17

C++17 features that we could consider (Source):

  • compile-time if constexpr
  • initializers for if and switch
  • temporary materialization
  • structured bindings (assignment decomposition)
  • Templates
    • fold-expressions ( … )
    • class template argument deduction tuple t(4, 3, 2.5)
    • non-type template parameters declared with auto
  • Namespaces
    • simplified nested namespaces
    • using-declaration declaring multiple names
    • attribute namespaces don’t have to repeat
  • new attributes:
    • [[fallthrough]]
    • [[maybe_unused]]
    • [[nodiscard]]
  • __has_include

C++17 Excluded Features

  • u8 character literal (HLSL does not have 8-bit types)
  • made noexcept part of type system (HLSL does not have exceptions)
  • new order of evaluation rules (these changes don’t apply to HLSL)
  • lambda capture of *this (requires lambdas)
  • constexpr lambda (requires lambdas)
  • inline variables (requires linkage model changes)
  • guaranteed copy elision (requires construction & rvalue references)

C++20 and later

Adopting C++ 20 and later features is not under consideration at this time due to feasibility in existing implementations.