Skip to content

Dependencies on Chapter 23, "Unsafe code," in earlier chapters #211

Closed
@RexJaeschke

Description

@RexJaeschke

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

  1. sizeof (§23.6.9)

expressions.md:

  1. Except in an unsafe context (§23.2), the layout of arrays is unspecified.

  2. ... 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.

  3. 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).

  4. For an enum type T, the result of the expression sizeof(T) is a constant value equal to the size of its underlying type, as given above. For all other operand types, the sizeof operator is specified in §23.6.9.

  5. In an unsafe context ...

  6. 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.

  7. sizeof expressions, provided the unmanaged-type is one of the types specified in §23.6.9 for which sizeof returns a constant value.

lexical-structure.md

  1. 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

  2. | 'unsafe' | 'ushort' | 'using' | 'virtual' | 'void'

statements.md

  1. 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

  1. A third category of types, pointers, is available only in unsafe code §23.3.

  2. A non-enum constructed type shall not be used as an unmanaged_type §23.3.

  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?"

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions