-
Notifications
You must be signed in to change notification settings - Fork 86
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add support for function pointers #984
base: draft-v9
Are you sure you want to change the base?
Add support for function pointers #984
Conversation
|
||
In an unsafe context, several constructs are available for operating on pointers: | ||
*unmanaged_calling_convention* supports a small number of predefined conventions (`Cdecl`, `Stdcall`, `Thiscall`, and `Fastcall`, all of which are contextual keywords), which may be used standalone or as an *identifier* in an *unmanaged_calling_convention* identifier list. Other implementation-defined conventions are permitted, and multiple conventions can be combined by using an *identifier* list, possibly containing one or more of these predefined conventions. Lookup and processing for identifiers in this list is done in an implementation-defined manner. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are @Stdcall
and Stdc\u0061ll
required to mean the same thing as Stdcall
, or is that too implementation-defined?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Regarding Stdc\u0061ll
, §6.4.2, Unicode character escape sequences, states:
A Unicode escape sequence represents a Unicode code point. Unicode escape sequences are processed in identifiers (§6.4.3), character literals (§6.4.5.5), regular string literals (§6.4.5.6), and interpolated regular string expressions (§12.8.3). A Unicode escape sequence is not processed in any other location (for example, to form an operator, punctuator, or keyword).
This suggests that Stdc\u0061ll
and Stdcall
are equivalent. However, §6.4.4, Keywords, contains the following:
Just as with keywords, contextual keywords can be used as ordinary identifiers by prefixing them with the
@
character.Note: When used as contextual keywords, these identifiers cannot contain Unicode_Escape_Sequences. end note
If that Note is true, and that info can't be deduced from normative text, the Note should be made normative.
§6.4.3 Identifiers, contains the grammar for identifier
. See the detailed Note following it. After several readings of that, I am not completely convinced of the situation w.r.t @
.
@Nigel-Ecma, as you were heavily involved in the rewrite of this grammar, what is your opinion?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The impression I get from the draft PR is that delegate* unmanaged[Stdcall]<void>
uses a contextual keyword and shall be accepted by all implementations, but delegate* unmanaged[@Stdcall]<void>
uses an identifier and does not need to be accepted; an implementation might even define that the identifier lookup depends on using
directives. But I'm not sure the specification should give this freedom to implementations.
If that interpretation is intended, then this text in §6.4.4 Keywords
In certain cases the grammar is not enough to distinguish contextual keyword usage from identifiers. In all such cases it will be specified how to disambiguate between the two.
requires adding a disambiguation rule to §function-pointers, e.g.
If the unmanaged_calling_convention is
Cdecl
,Stdcall
,Thiscall
, orFastcall
, then it is a contextual keyword. Otherwise, it is an identifier.
But I feel it would be better to omit Cdecl
etc. from the grammar and instead always parse unmanaged_calling_convention as a list of identifiers, and then specify that these four identifiers shall be accepted by all implementations.
Is there any definition of what the
If nothing about semantics is being standardised then perhaps it would be better to leave the names entirely implementation-defined (so no contextual keywords) and add a note recommending these names in implementations that target ECMA-335. Portable C# applications would then have to put |
There are two parts of this feature that are not covered by this PR, but that need to be considered:
RESOLVED!
## Part 1: Organizing the unsafe-related textThe following sections either need detailed text (which I have written, but it is not in this PR) to be added that is unsafe-specific, or will need forward pointers to the unsafe chapter, which would have the text added there:
12.6.3.4 Input types
12.6.3.5 Output types
12.6.3.7 Output type inferences
12.6.3.10 Lower-bound inferences
12.6.3.11 Upper-bound inferences
12.6.4.3 Better function member
12.6.4.5 Better conversion from expression
12.8.9 Invocation expressions|12.8.9.1 General
See Issue #750 for a discussion on dealing with unsafe situations outside of the unsafe chapter. The following two sections show the alternatives for one of these sections.
Part 1 example - New unsafe text in Chapter 12
12.6.3.7 Output type inferences
We might also want to add a backward pointer to this section from the unsafe chapter.
Part 1 example - New unsafe text in Chapter 23
12.6.3.7 Output type inferences
…
This subclause is extended in unsafe code (§xx).
23.6.1.x Output type inferences
In §12.6.3.7, the following bullet is added between the second and third bullets:
E
is an address-of method group andT
is a function pointer type with parameter typesT1..Tk
and return typeTb
, and overload resolution ofE
with the typesT1..Tk
yields a single method with return typeU
, then a lower-bound inference is made fromU
toTb
.[The problem with this approach is that the reader has to flip between two chapters to understand this, and over time, paras might be added, removed, or rearranged back in 12.6.3.7, rendering the relative para instructions used here, incorrect. And we don't want to replicate all the bullets from 12.6.3.7 here.]Part 2: The library type
System.Runtime.CompilerServices.UnmanagedCallersOnlyAttribute
Spec'ing of this attribute has not yet been resolved. However, Rex added this type to C.3, but TG2 might decider to remove it. Following is a message thread between Fred Silberberg and me in March 2022:
Comment 9: “UnmanagedCallersOnlyAttribute”
This part of the proposal looks like implementation detail. As such, I don’t mention it in my C# standard proposal. Is that reasonable?
The MS proposal doesn’t show any examples of initializing an unmanaged function pointer using
&
. I’m guessing it might go something like this:Am I on the right track?
2022-03-24 Fred Silberberg responded: No, this definitely cannot be removed. It affects your Comment 6 [method signature and calling convention combination], and also affects the ability for methods to be called without taking a function pointer to them. It is very explicitly not an implementation detail.
2022-03-25 Rex replied: Thanks, @333fred for your quick response.
Re my Comment #9, I still haven't fully digested your response and the attribute in question, but I wanted to bring to your attention a statement from the C# Standard's Introduction:
My concern is, "How much of the machinery should be exposed in a standard that does not require .NET/CLI? That is, is this attribute part of the support needed by the minimum CLI features required by this C# standard?" My guess is that you will answer, "Yes, it's needed" and I'm OK with that.
2022-03-25 Fred replied: I will indeed. Since the presence of the attribute determines whether a method group can be converted to an unmanaged function pointer, it needs to be present in the spec. If a minimum cli didn't have the attribute, it would probably be fine technically: users of that cli would just never be able to directly convert a method group to an unmanaged function pointer.