-
Notifications
You must be signed in to change notification settings - Fork 45
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Defining enums and bitmasks using enum
vs. as constants
#273
Comments
Mar 14 meeting:
|
I just remembered we previously chose to use |
Actually Vulkan does use |
Also... naming question, should we drop "Flags" from the name since there is now just one type (the uint64_t typedef) instead of two (the uint32_t typedef and the enum)? e.g. WGPUBufferUsageFlags -> WGPUBufferUsage |
IMO, we should drop "Flags" to match the naming in the JS API |
WebIDL has both names (though the "Flags" one is not exposed to JS): typedef [EnforceRange] unsigned long GPUBufferUsageFlags;
[Exposed=(Window, Worker), SecureContext]
namespace GPUBufferUsage {
const GPUFlagsConstant MAP_READ = 0x0001; I think the C equivalent would arguably be: typedef uint64_t GPUBufferUsageFlags;
static const GPUBufferUsageFlags GPUBufferUsage_MapRead = 0x0001; but of course the "Flags" name becomes exposed to the application unlike in JS. |
Jul 18 meeting:
|
Originally posted by @kainino0x in #270 (comment)
Ah... unfortunate. I dug a little to figure out why this was the case in Vulkan. Clang makes it clear - and this is also the reason Force32 is 0x7fffffff instead of 0xffffffff.
warning: ISO C restricts enumerator values to range of 'int' (4294967295 is too large) [-Wpedantic]
C++ seems to have no such complaints for
enum class
, so Dawn should still be able to do the thing we do in C++ to make strongly-typed bitflags fromenum class
.C++ also seems to have no complains for
enum
, which means we could useenum
behind#ifdef __cplusplus
, for added type safety. Doing so would be consistent with #159, where we were going to do theoperator|
thing to make C++ happy with our usage ofenum
s as bitflags. But having separate C and C++ definitions of entire enums is annoying, and also sketchy - it almost certainly breaks ABI compatibility between the C and C++ versions.So I think we are going to have to scrap the
operator|
thing and just use 64-bit constants. Too bad.Actually this raises another interesting point - if we extend enums outside the enum definition, then it becomes easy to write a switch that passes the exhaustiveness check, but is not actually exhaustive. Of course, this was always true of bitflags, and generally true if you cast numbers to enums, but those are corner cases.
This is probably fine, it just adds a little bit of a false sense of security. Almost certainly better to get some warnings than no warnings.
Most enums won't be commonly in application code anyway. The enums we do pass out to the application may get extended, but for most enums, we should never start returning new values to existing applications unless we enable some feature, so exhaustivity over the core enum is all that really matters.
For reference, I think the only enums where we may suddenly start passing out new values to the application are
FeatureName
(in AdapterEnumerateFeatures, but not DeviceEnumerateFeatures) andWGSLFeatureName
(in GetInstanceFeatures or whatever we end up calling it). NotSType
, I think, if we solve #272.Maybe... after we stabilize, we should just never change the enum definitions and only extend them using
static const
? (maybe even rename Force32 to indicate it's there to make the enum extensible/non-exhaustive, as anyone writing exhaustive switches will end up having to type Force32)(Aside, apparently there is a gcc/clang flag that checks for exhaustive switches even with default. I am now tempted to try this in Dawn. https://brevzin.github.io/c++/2019/08/01/enums-default/#the-warning-that-exists)
The text was updated successfully, but these errors were encountered: