The Windows Runtime PassArray is a read-only array, even though it isn’t declared const

Raymond

As I noted some time ago, the Windows Runtime PassArray pattern passes a read-only non-owning counted array which is nevertheless not declared as const.

Indeed, if you try to force the array type to be const in your IDL declaration:

HRESULT SetData([in] UINT32 dataSize, [in, size_is(dataSize)] const INT32* data);

The const is ignored, and the resulting metadata declares the parameter as non-const.

There are a few reasons for this, partly intentional, and partly a technicality.

The technicality is that the const attribute is lost because Windows Runtime methods are described by metadata that physically takes the form of an ECMA-335 assembly (though restricted to a very limited subset of full ECMA-335), and ECMA-335 does not have const. Therefore Windows Runtime metadata cannot have const.

Mind you, this is an unsatisfying explanation since it’s semi-circular. Windows Runtime metadata doesn’t have const because the designers chose a format that doesn’t support const, and it’s okay to have chosen a format that doesn’t support const because Windows Runtime metadata doesn’t use const.

But really, if they really wanted const, then they would have chosen some other file format that does support const.

The Windows Runtime does not have const because the concept cannot be expressed in most programming languages,¹ and the Windows Runtime intends to be language-independent. Limiting the feature set of the Windows Runtime type system makes it more likely that it can be consumed by a broad range of programming languages.

¹ Indeed, it’s really only C, C++ and now Rust that have such a concept. The C++ projections do represent the array as const: It is a const Platform::Array in C++/CX, and it is a winrt::array_view<T const> in C++/WinRT. Similarly, the Rust projection represents the array as an immutable reference.

10 comments

Comments are closed. Login to edit/delete your existing comments

  • Paulo Pinto

    D, Delphi and Swift also have such concept.

    And if we stray from mainstream path, languages like ML family, Active Oberon and Modula-3 also do have such concept.

    • Danstur

      Swift’s idea of const is as I understand it pretty much the same as const in c# or java but not the same concept as c++ has.

      I assume the same is true for the other languages listed, at least I don’t remember const correctness ever being an issue when we learned Delphi in highschool (boy I’m getting old)

      • Paulo Pinto

        Swift is immutable by default, so actually is the same const as ML languages, which you also find in Rust.

        func SetData (dataSize: UInt32, data : UnsafePointer) -> HRESULT

        If you wanted to be able to change data, then it would be

        func SetData (dataSize: UInt32, data : UnsafeMutablePointer) -> HRESULT

        Delphi in 2021 is a bit different than those highschool days, similarly with the proper type alias it would be,

        function SetData(dataSize: UINT32; const data: array of INT32): HRESULT;
    • Virgo Pärna

      I’m not sure about Delphi. In Delphi const means, that value of pointer cannot be changed, pointed value can be changed. So Delphi

      const data: PINT

      would be more like C

      int * const data
    • jahns@chemie.uni-hamburg.de

      I’m not sure what Raymond meant by the concept, because const is in some ways extremely specific. But many languages that borrow from Fortran and Fortran itself have

      INTENT(IN)

      argument (what C calls parameters) declarations. Those have mostly the same implications as const for non-nested types and are a bit more strict for stuff containing pointers. While C-derived languages don’t mind modifications to pointers passed as members of const declared structs, Fortran would disallow that.

      It would be interesting to know for which language interoperability they were shooting for back then.

  • Fabian Schmied

    The ECMA-335 metadata format can actually express “const” via its concept of “custom modifiers”.

    Quoting from ECMA-335, Partition II, 7.1.1: “For example, the const qualifier in the C programming language can be modelled with an optional modifier […].”

    • IS4

      Indeed. This is heavily used by C++/CLI assemblies, where you can easily find modreq(System.Runtime.CompilerServices.IsConst).