DirectXShaderCompiler icon indicating copy to clipboard operation
DirectXShaderCompiler copied to clipboard

C++11 enums don’t work as integer constants as expected

Open devshgraphicsprogramming opened this issue 2 years ago • 9 comments
trafficstars

Is your feature request related to a problem? Please describe.

Thanks to HLSL2021 I can share enumeration declarations between C++ and HLSL202x.

Bug Report: However whenever I declare the enum class HLSL does not complain until I actually try to use the scoped enum. Seems that enum class passes through your tokenizer unharmed, but then the rest of the logic is gone.

Describe the solution you'd like

For the compiler to support scope enum lookup enum_t:: without errors.

Describe alternatives you've considered

Not using scoped enums but a lot of my C++ code I want to expose to HLSL already does, so not fun.

Additional context

Here's a repro: https://godbolt.org/z/1TdYh9E1a

Just my 2c, but I think enum class as a feature in C++ leaves much to be desired and don't know that the goal of future HLSL design should be driven primarily by the metric of "code shareability with C++."

jeremyong avatar Aug 05 '23 18:08 jeremyong

Just my 2c, but I think enum class as a feature in C++ leaves much to be desired and don't know that the goal of future HLSL design should be driven primarily by the metric of "code shareability with C++."

would you care to elaborate on the "much to be desired" ?

Sure. As used currently, people often declare an enum class not specifically for strong-typing, but in order to get scoped enum field declarations. In exchange, you lose the ability to easily use enum class fields as array indexing operators, bit flags, or myriad other use cases. You can't provide a conversion operator for enum class types to circumvent this issue either, so you end up resorting to a soup of macros or nasty infectious templates to provide that behavior. The syntax itself is non-obvious (both enum class and enum struct map to the same type of declaration with no distinction, but my god what an awful naming scheme that is). I think we're better off making regular enum fields have proper lexical scoping first.

jeremyong avatar Aug 06 '23 18:08 jeremyong

In exchange, you lose the ability to easily use enum class fields as array indexing operators, bit flags, or myriad other use cases.

you can use them as bit flags, you just need to declare the bitwise operators for them.

I think its great because it stops you "accidentally" bitwise-op'ing unrelated bitflags.

You can't provide a conversion operator for enum class types to circumvent this issue either, so you end up resorting to a soup of macros or nasty infectious templates to provide that behavior.

thats kinda why we have a core::bitflag<> in our engine to deal with all that.

HLSL 2017 and later all support C++11-style enum class declarations, and the accessing seems to work for me (Compiler Explorer Link).

Can you provide an example of what doesn't work for you? The link you provided doesn't actually have an enum class declaration.

llvm-beanz avatar Aug 15 '23 17:08 llvm-beanz

yeah when you change the enum to class add scope the enums in the example I gave then it starts complaining about not being able to use a scoped enum as as integral expression (whereas it uses an unscoped one just fine) https://godbolt.org/z/Pxd1zacr7

I’ve transferred this issue over to DXC because this is a bug not a language feature request.

llvm-beanz avatar Aug 16 '23 13:08 llvm-beanz

hmm it works with correct static_cast substitute of a C-style cast https://godbolt.org/z/M6Kna6r7s

The only annoying thing is that DXC doesn't recognize enum class as being something you can template on https://godbolt.org/z/8hqrj1ezr

btw also seems that concepts like integral_constant<Enum,Enum Val> are busted https://godbolt.org/z/EGaesxvE1