메모
이 문서는 기능 사양입니다. 사양은 기능의 디자인 문서 역할을 합니다. 여기에는 기능 디자인 및 개발 중에 필요한 정보와 함께 제안된 사양 변경 내용이 포함됩니다. 이러한 문서는 제안된 사양 변경이 완료되고 현재 ECMA 사양에 통합될 때까지 게시됩니다.
기능 사양과 완료된 구현 간에 약간의 불일치가 있을 수 있습니다. 이러한 차이는 관련된 LDM(언어 디자인 모임) 노트에 기록됩니다.
규격문서에서 C# 언어 표준으로 기능 사양을 채택하는 과정에 대해 자세히 알아볼 수 있습니다.
챔피언 이슈: https://github.com/dotnet/csharplang/issues/6065
요약
이는 nint/ 형식이 nuintSystem.IntPtr/기본 형식과 구별되는 초기 네이티브 정수 기능(System.UIntPtr)에 대한 수정 버전입니다.
요컨대, 이제 nint/nuintSystem.IntPtr관련하여 / 경우처럼 System.UIntPtrintSystem.Int32별칭을 지정하는 간단한 형식으로 취급합니다.
System.Runtime.CompilerServices.RuntimeFeature.NumericIntPtr 런타임 기능 플래그는 이 새로운 동작을 트리거합니다.
디자인
8.3.5 단순 형식
C#은 단순 형식이라는 미리 정의된 struct 형식 집합을 제공합니다. 단순 형식은 키워드를 통해 식별되지만 이러한 키워드는 아래 표에 설명된 대로 struct 네임스페이스의 미리 정의된 System 형식에 대한 별칭일 뿐입니다.
| 키워드 | 별칭 형식 |
|---|---|
sbyte |
System.SByte |
byte |
System.Byte |
short |
System.Int16 |
ushort |
System.UInt16 |
int |
System.Int32 |
uint |
System.UInt32 |
nint |
System.IntPtr |
nuint |
System.UIntPtr |
long |
System.Int64 |
ulong |
System.UInt64 |
char |
System.Char |
float |
System.Single |
double |
System.Double |
bool |
System.Boolean |
decimal |
System.Decimal |
[...]
8.3.6 정수 계열 형식
C#은 char 정수 계열 형식을 지원합니다. [...]
8.8 관리되지 않는 형식
즉, unmanaged_type 다음 중 하나입니다.
-
sbyte,byte,short,ushort,int,uint,nint,nuint,long,ulong,char,float,double,decimal또는bool. - 모든 열거형 타입 .
- 구성된 형식이 아니며 오직 unmanaged_type필드만 포함하는 사용자 정의 struct_type.
- 안전하지 않은 코드에서는 pointer_type.
10.2.3 암시적 숫자 변환
암시적 숫자 변환은 다음과 같습니다.
-
sbyte에서short,int,nint,long,float,double또는decimal. -
byte에서short,ushort,int,uint,nint,nuint,long,ulong,float,double또는decimal. -
short부터int,nint,long,float,double또는decimal까지. -
ushort에서int,uint,nint,nuint,long,ulong,float,double또는decimal. -
int에서nint,long,float,double또는decimal. -
uint부터nuint,long,ulong,float,double또는decimal까지. -
nint에서long,float,double또는decimal. -
nuint에서ulong,float,double또는decimal. -
long에서float,double또는decimal로. -
ulong에서float,double또는decimal로. -
char에서ushort,int,uint,nint,nuint,long,ulong,float,double또는decimal. -
float부터double.
[...]
10.2.11 암시적 상수 식 변환
암시적 상수 식 변환은 다음과 같은 변환을 허용합니다.
-
constant_expression 값이 대상 형식 범위 내에 있는 경우 형식
intsbyte형식byte,short,ushort,uint,nint,ulong또는 변환할 수 있습니다. [...]
10.3.2 명시적 숫자 변환
명시적 숫자 변환은 numeric_type을 numeric_type으로 변환하는 것을 의미하며, 이는 암시적 숫자 변환이 존재하지 않는 경우입니다.
-
sbyte부터byte,ushort,uint,nuint,ulong또는char까지. -
byte부터sbyte또는char. -
short에서sbyte,byte,ushort,uint,nuint,ulong또는char. -
ushort에서sbyte,byte,short또는char까지. -
int에서sbyte,byte,short,ushort,uint,nuint,ulong또는char. -
uint에서sbyte,byte,short,ushort,int,nint또는char. -
long에서sbyte,byte,short,ushort,int,uint,nint,nuint,ulong또는char. -
nint에서sbyte,byte,short,ushort,int,uint,nuint,ulong또는char. -
nuint에서sbyte,byte,short,ushort,int,uint,nint,long또는char. -
ulong에서sbyte,byte,short,ushort,int,uint,nint,nuint,long또는char. -
char에서sbyte,byte또는short로. -
float에서sbyte,byte,short,ushort,int,uint,nint,nuint,long,ulong,char또는decimal. -
double에서sbyte,byte,short,ushort,int,uint,nint,nuint,long,ulong,char,float또는decimal. -
decimal에서sbyte,byte,short,ushort,int,uint,nint,nuint,long,ulong,char,float또는double.
[...]
10.3.3 명시적 열거형 변환
명시적 열거형 변환은 다음과 같습니다.
-
sbyte,byte,short,ushort,int,uint,nint,nuint,long,ulong,char,float,double또는decimal에서 임의의 enum_type로. - 어떤 enum_type 에서
sbyte,byte,short,ushort,int,uint,nint,nuint,long,ulong,char,float,double또는decimal로. - enum_type에서 다른 enum_type로.
12.6.4.7 더 나은 변환 대상
두 가지 형식 T₁ 및 T₂이 주어졌을 때, T₁는 더 나은 변환 대상이 될 수 있습니다. 다음 중 하나가 성립하면: T₂.
-
T₁T₂암시적 변환이 존재하며T₂T₁암시적 변환이 없습니다. -
T₁은Task<S₁>이고,T₂은Task<S₂>이며,S₁는S₂보다 더 나은 변환 대상입니다. -
T₁는S₁또는S₁?이며,S₁는 부호 있는 정수형입니다. 그리고T₂는S₂또는S₂?이며,S₂는 부호 없는 정수형입니다. 구체적으로: [...]
12.8.12 요소 액세스
[...] argument_list 식 수는 array_type순위와 같아야 하며 각 식은 int, uint, nint, nuint, long또는 ulong, 형식이거나 이러한 형식 중 하나 이상으로 암시적으로 변환할 수 있어야 합니다.
11.8.12.2 배열 액세스
[...] argument_list 식 수는 array_type순위와 같아야 하며 각 식은 int, uint, nint, nuint, long또는 ulong, 형식이거나 이러한 형식 중 하나 이상으로 암시적으로 변환할 수 있어야 합니다.
[...] P[A]형식 배열 접근의 런타임 처리는 P이 primary_no_array_creation_expression의 array_type이고 A이 argument_list인 경우, 다음 단계로 구성됩니다. [...]
-
argument_list 인덱스 식은 왼쪽에서 오른쪽으로 순서대로 평가됩니다. 각 인덱스 식을 평가한 후에는
int,uint,nint,nuint,long,ulong중 하나로 암시적으로 변환됩니다. 암시적 변환이 존재하는 이 목록의 첫 번째 형식이 선택됩니다. [...]
12.8.16 후위 증가 및 감소 연산자
단항 연산자 오버로드 확인은 특정 연산자 구현을 선택하기 위해 적용됩니다. 미리 정의된 ++ 및 -- 연산자는 sbyte, byte, short, ushort, int, uint, nint, nuint,long, ulong, char, float, double, decimal및 모든 열거형 형식에 대해 존재합니다.
12.9.2 단항 더하기 연산자
미리 정의된 단항 더하기 연산자는 다음과 같습니다.
...
nint operator +(nint x);
nuint operator +(nuint x);
12.9.3 단항 빼기 연산자
미리 정의된 단항 빼기 연산자는 다음과 같습니다.
정수 부정:
... nint operator –(nint x);
12.8.16 후위 증가 및 감소 연산자
미리 정의된 ++ 및 -- 연산자는 sbyte, byte, short, ushort, int, uint, nint, nuint, long, ulong, char, float, double, decimal및 모든 열거형 형식에 대해 존재합니다.
11.7.19 기본값 식
또한 형식이 , sbyte, byte, short, ushort, int, nuint, , long, ulong, char, float, double, decimal 또는 열거형 형식 중 하나이면 bool, 상수 식입니다.
12.9.5 비트 반전 연산자
미리 정의된 비트 보수 연산자는 다음과 같습니다.
...
nint operator ~(nint x);
nuint operator ~(nuint x);
12.9.6 접두사 증가 및 감소 연산자
미리 정의된 ++ 및 -- 연산자는 sbyte, byte, short, ushort, int, uint, nint, nuint, long, ulong, char, float, double, decimal및 모든 열거형 형식에 대해 존재합니다.
12.10 산술 연산자
12.10.2 곱하기 연산자
미리 정의된 곱셈 연산자는 아래에 나열되어 있습니다. 연산자는 모두 x 및 y곱을 계산합니다.
정수 곱하기:
... nint operator *(nint x, nint y); nuint operator *(nuint x, nuint y);
12.10.3 나눗셈 연산자
미리 정의된 나누기 연산자는 다음과 같습니다. 연산자는 모두 x 및 y몫을 계산합니다.
정수 나누기:
... nint operator /(nint x, nint y); nuint operator /(nuint x, nuint y);
12.10.4 나머지 연산자
미리 정의된 나머지 연산자는 아래에 나열되어 있습니다. 연산자는 모두 xy사이의 나머지 부분을 계산합니다.
정수 나머지:
... nint operator %(nint x, nint y); nuint operator %(nuint x, nuint y);
12.10.5 더하기 연산자
정수 추가:
... nint operator +(nint x, nint y); nuint operator +(nuint x, nuint y);
12.10.6 빼기 연산자
정수 빼기:
... nint operator –(nint x, nint y); nuint operator –(nuint x, nuint y);
12.11 시프트 연산자
미리 정의된 시프트 연산자는 아래에 나열되어 있습니다.
왼쪽으로 이동:
... nint operator <<(nint x, int count); nuint operator <<(nuint x, int count);오른쪽으로 이동:
... nint operator >>(nint x, int count); nuint operator >>(nuint x, int count);>>연산자는 아래 설명된 대로 계산된 비트 수만큼x오른쪽으로 이동합니다.x형식이int,nint또는long경우 낮은 순서의x비트가 삭제되고, 나머지 비트는 오른쪽으로 이동하고,x음수가 아니면 상위 빈 비트 위치가 0으로 설정되고x음수이면 1로 설정됩니다.x형식이uint,nuint또는ulong경우 낮은 순서의x비트가 삭제되고, 나머지 비트가 오른쪽으로 이동되고, 상위 빈 비트 위치가 0으로 설정됩니다.서명되지 않은 시프트 오른쪽:
... nint operator >>>(nint x, int count); nuint operator >>>(nuint x, int count);
미리 정의된 연산자의 경우 이동할 비트 수는 다음과 같이 계산됩니다. [...]
-
x유형이nint또는nuint시프트 수는 32비트 플랫폼의 하위 5비트count또는 64비트 플랫폼의 하위 6비트count의해 제공됩니다.
12.12 관계형 및 형식 테스트 연산자
12.12.2 정수 비교 연산자
미리 정의된 정수 비교 연산자는 다음과 같습니다.
...
bool operator ==(nint x, nint y);
bool operator ==(nuint x, nuint y);
bool operator !=(nint x, nint y);
bool operator !=(nuint x, nuint y);
bool operator <(nint x, nint y);
bool operator <(nuint x, nuint y);
bool operator >(nint x, nint y);
bool operator >(nuint x, nuint y);
bool operator <=(nint x, nint y);
bool operator <=(nuint x, nuint y);
bool operator >=(nint x, nint y);
bool operator >=(nuint x, nuint y);
12.12 논리 연산자
12.12.2 정수 논리 연산자
미리 정의된 정수 논리 연산자는 다음과 같습니다.
...
nint operator &(nint x, nint y);
nuint operator &(nuint x, nuint y);
nint operator |(nint x, nint y);
nuint operator |(nuint x, nuint y);
nint operator ^(nint x, nint y);
nuint operator ^(nuint x, nuint y);
12.22 상수 식
상수 식은 값 형식 또는 참조 형식일 수 있습니다. 상수 식이 값 형식인 경우 sbyte, byte, short, ushort, int, uint, nint, nuint, long, ulong, char, float, double, decimal, bool, 또는 열거형 형식 중 하나여야 합니다.
[...]
암시적 상수 식 변환을 사용하면 상수 식의 값이 대상 형식 범위 내에 있는 경우 int, sbytebyte, short, ushort, uint, nint, nuint, 또는 ulong형식의 상수 식을 변환할 수 있습니다.
17.4 배열 요소 접근
배열 요소는 양식의 A[I₁, I₂, ..., Iₓ] 식을 사용하여 액세스합니다. 여기서 A 배열 형식의 식이고 각 Iₑint, uint, nint, nuint,long, ulong형식의 식이거나 이러한 형식 중 하나 이상으로 암시적으로 변환될 수 있습니다. 배열 요소 액세스의 결과는 변수, 즉 인덱스에 의해 선택된 배열 요소입니다.
23.5 포인터 변환
23.5.1 일반
[...]
또한 안전하지 않은 컨텍스트에서는 다음과 같은 명시적 포인터 변환을 포함하도록 사용 가능한 명시적 변환 집합이 확장됩니다.
- 어떠한 pointer_type에서 다른 pointer_type로.
-
sbyte,byte,short,ushort,int,uint,nint,nuint,long, 또는ulong에서 pointer_type로. - 모든 pointer_type에서,
sbyte,byte,short,ushort,int,uint,nint,nuint,long또는ulong으로.
23.6.4 포인터 요소 액세스
[...] P[E]폼의 포인터 요소 액세스에서 Pvoid*이외의 포인터 형식의 식이어야 하며, Eint, uint, nint, nuint,long또는 ulong암시적으로 변환할 수 있는 식이어야 합니다.
23.6.7 포인터 산술 연산
안전하지 않은 컨텍스트에서 + 연산자와 – 연산자는 void*제외한 모든 포인터 형식의 값에 적용할 수 있습니다. 따라서 T*모든 포인터 형식에 대해 다음 연산자가 암시적으로 정의됩니다.
[...]
T* operator +(T* x, nint y);
T* operator +(T* x, nuint y);
T* operator +(nint x, T* y);
T* operator +(nuint x, T* y);
T* operator -(T* x, nint y);
T* operator -(T* x, nuint y);
포인터 형식 P의 표현식 T*와 N, int, nuint, 또는 long형식의 표현식 ulong가 주어졌을 때, 표현식 P + N과 N + P는 T*로 지정된 주소에 N * sizeof(T)를 더한 결과로 P 형식의 포인터 값을 계산합니다. 마찬가지로 식 P – NT*지정한 주소에서 N * sizeof(T) 빼서 발생하는 P 형식의 포인터 값을 계산합니다.
다양한 고려 사항
주요 변경 내용
이 디자인의 주요 영향 중 하나는 System.IntPtr 및 System.UIntPtr 일부 기본 제공 연산자(변환, 단항 및 이진)를 얻을 수 있다는 것입니다.
여기에는 checked 연산자가 포함됩니다. 즉, 해당 형식에서 다음 연산자는 오버플로될 때 예외를 던집니다.
IntPtr + intIntPtr - intIntPtr -> intlong -> IntPtrvoid* -> IntPtr
메타데이터 인코딩
이 디자인은 nint사용하지 않고 nuint 및 System.IntPtr 단순히 System.UIntPtr 및 System.Runtime.CompilerServices.NativeIntegerAttribute내보낼 수 있음을 의미합니다.
마찬가지로 메타데이터 NativeIntegerAttribute 로드하는 경우 무시될 수 있습니다.
C# feature specifications