microsoft / xlang

MIT License
877 stars 103 forks source link

Ability to have real constants in WinRT #790

Closed JaiganeshKumaran closed 1 year ago

JaiganeshKumaran commented 1 year ago

Proposal: Ability to have real constants in WinRT

Unlike .NET metadata, WinRT metadata doesn't allow defining constants in a runtime class. This made users use static properties for constants, but it means now instead of nothing the value at compile time and simply embedding it as a literal, you have to make an expensive virtual call on a statics interface on the runtime class factory every time. They also don't have noexcept attribute because it didn't exist then, so language projections will check HRESULT even if they are guaranteed to succeed. A good example is the Windows.UI.Colors runtime class.

There are also few instances of static properties used for constants when really what they were trying to express is an enumeration. I believe this was done because, before C++11, you could not specify the underlying type, thus WinRT picked up that and only supported the underlying type of Int32 or UInt32 (which is what Microsoft's C++ compiler would use), though not a problem anymore. They could've used a 32-bit integer with an enumeration but didn't

This two runtime classes come to my mind which do this: GattProtocolError and GattPresentationFormatTypes.

Now coming to MIDL, there really isn't the notion of instantiating a struct which would be required to make members of Windows.UI.Colors constant. It does, however, already support literals (mainly for attributes). WinRT value types don't have a constructor so I would recommend using a syntax to assign each field of it (similar to C's designated initializer or C#'s property setting).

struct Color
{
    UInt8 Alpha;
    UInt8 Red;
    UInt8 Green;
    UInt8 Blue;
};

// Constant of type UInt8.
const UInt8 Zero = 0; // literal syntax already supported.

// Constant of type Color.
const Color Black { A = 0, R = 0, G = 0, B = 0 };  // new literal syntax probably.

Open questions

Should constant members be only part of runtime classes or should they be able to be inside structs? I would recommend "runtime classes only" just for consistency.

Should you be able to embed another constant like writing "Zero" instead of "0" there? And should you be able to arithmetic operators (not sure if you can in attributes already or not)? I would recommend against it because MIDL is not a programming language and should be only for the job that it was designed for - that is generating metadata and generating headers for C/C++ (though now C++/WinRT and ABI/WinRT packages do that for most people). Because if you do add arithmetic operators, people may also expect operators for other things like concatenating strings.

Summary

Support defining constants of value types. Support specifying the underlying type of an enumeration.

github-actions[bot] commented 1 year ago

This issue is stale because it has been open 10 days with no activity. Remove stale label or comment or this will be closed in 5 days.