Description
Chapter 23, "Unsafe code," starts out by saying the following:
An implementation that does not support unsafe code is required to diagnose any usage of the keyword unsafe.
The remainder of this clause, including all of its subclauses, is conditionally normative.
My understanding has long been that a conforming implementation need not implement any of Chapter 23, so long as it diagnoses any usage of the keyword unsafe
.
Having worked with conditionally normative features in other specs, and where one "extended" spec adds on/changes a "base" spec, in the strictest sense, the chapters prior to 23 should make no mention of 23. Then in 23, we say how things in prior chapters are impacted.
I ran into this recently when working on grammar validation. It seems to me that ultimately, we should publish two grammars: one for the core/required language, the other for the extended language (which is core + unsafe stuff).
My validation test grammar does not include that for the unsafe chapter. During validation, I discovered that in one place only in chapters prior to 23, we refer to the extended grammar in 23, as follows:
12.7.13 The sizeof operator
The
sizeof
operator returns the number of 8-bit bytes occupied by a variable of a given type. The type specified as an operand to sizeof shall be an unmanaged_type (§23.3).sizeof_expression : 'sizeof' '(' unmanaged_type ')' ;
So, if I as an implementer of the base spec only, the grammar rule unmanaged_type does not exist, so its use in the sizeof_expression rule in meaningless, as is the reference to that rule in the narrative above.
I was curious as to what other references to 23 we might make in narrative in early chapters, and here's what a search for relevant occurrences of the word "unsafe" reported:
[In some cases, the reference to "unsafe" is hidden in the link as the name of chapter 23.]
enums.md
- sizeof (§23.6.9)
expressions.md:
-
Except in an unsafe context (§23.2), the layout of arrays is unspecified.
-
... where each «Tx» is the type of the corresponding expression «ex». The expression used in a member-declarator shall have a type. Thus, it is a compile-time error for an expression in a member-declarator to be
null
or an anonymous function. It is also a compile-time error for the expression to have an unsafe type. -
The
sizeof
operator returns the number of 8-bit bytes occupied by a variable of a given type. The type specified as an operand to sizeof shall be an unmanaged_type (§23.3). -
For an enum type
T
, the result of the expressionsizeof(T)
is a constant value equal to the size of its underlying type, as given above. For all other operand types, thesizeof
operator is specified in §23.6.9. -
In an unsafe context ...
-
When a local variable or a value parameter is captured by an anonymous function, the local variable or parameter is no longer considered to be a fixed variable (§23.4), but is instead considered to be a moveable variable. However, captured outer variables cannot be used in a
fixed
statement (§23.7), so the address of a captured outer variable cannot be taken. -
sizeof
expressions, provided the unmanaged-type is one of the types specified in §23.6.9 for whichsizeof
returns a constant value.
lexical-structure.md
-
If a sequence of tokens can be parsed (in context) as a simple_name (§12.7.3), member_access (§12.7.5), or pointer_member_access (§23.6.3) ending with a type_argument_list (§9.4.2), the token immediately following the closing
>
token is examined. If it is one of -
| 'unsafe' | 'ushort' | 'using' | 'virtual' | 'void'
statements.md
- It is a compile-time error for an iterator block to contain an unsafe context (§23.2). An iterator block always defines a safe context, even when its declaration is nested in an unsafe context.
types.md
-
A third category of types, pointers, is available only in unsafe code §23.3.
-
A non-enum constructed type shall not be used as an unmanaged_type §23.3.
-
A type_argument shall not be a pointer type §23. Each type argument shall satisfy any constraints on the corresponding type parameter §15.2.5.
-
- A type parameter cannot be used as an unmanaged_type §23.3. end note
Clearly, it would require a non-trivial effort to strictly separate early chapters from 23, and I have no opinion right now, as to whether we should do that. My main interest is "What to do with the forward reference to the grammar rule unmanaged_type from the sizeof_expression rule?"