Search code examples
syntaxdefinitioncilvalue-typeilasm

How to declare a value type in CIL: `.class value` or just `.class`?


I have taken a look at a C# struct FooStruct in ILDASM, and have seen the following:

enter image description here

ILDASM here displays two differing declarations:

  • one starting with .class value public (rear window & front window's title bar)
  • one starting with just .class public (front window)

And I wonder which syntax (if not both) is the correct one for declaring a value type? Is the value modifier strictly necessary, or optional, or a syntax error?


Solution

  • Short answer: Value type definitions only require extends [mscorlib]System.ValueType; the value attribute appears to be optional and has no apparent effect.

    I assume that the CLI specification (ECMA-335) would be the best place to look for an authorative answer.

    MUST a value type definition include the value attribute?

    Section II.10 deals with defining types. More specifically, subsection II.10.1.3 states:

    The type semantic attributes specify whether an interface, class, or value type shall be defined. … If [the interface] attribute is not present and the definition extends (directly or indirectly) System.ValueType, and the definition is not for System.Enum, a value type shall be defined (§II.13). Otherwise, a class shall be defined (§II.11).

    The value attribute is not mentioned at all in the whole section.

    Conclusion: A correct value type definition does not have to include value. Deriving from System.ValueType is sufficient.

    MAY a value type definition include the value modifier?

    The CLI standard also contains a grammar for ILASM (in section VI.C.3). According to that grammar, there exists a value attribute for .class type definitions. I additionally searched the standard for concrete value type definitions and found these examples:

    • .class public sequential ansi serializable sealed beforefieldinit System.Double extends System.ValueType …
    • .class private sealed Rational extends [mscorlib]System.ValueType …
    • .class value sealed public MyClass extends [mscorlib]System.ValueType …

    Conclusion: A value attribute may be included in a value type definition.

    And what does the value attribute MEAN?

    I tried to compile these three IL type definitions into an assembly:

    .class       public sealed … A extends [mscorlib]System.ValueType { … }
    .class value public sealed … B extends [mscorlib]System.ValueType { … }
    .class value public sealed … C extends [mscorlib]System.Object    { … }  // !!!
    

    There was no compilation error, even though the value attribute is used in a reference type declaration (see last line). Looking at the resulting assembly using Visual Studio 2012's Object Browser reveals two value types (struct) A and B, and one reference type (class) C.

    Speculation: The presence of the value attribute has no effect whatsoever on the type definition. It is only there as a potential aid for humans in spotting value type definitions.