Megosztás a következőn keresztül:


Nem aláírt jobb műszak operátor

Jegyzet

Ez a cikk egy funkcióspecifikáció. A specifikáció a funkció tervezési dokumentumaként szolgál. Tartalmazza a specifikáció javasolt módosításait, valamint a funkció tervezése és fejlesztése során szükséges információkat. Ezeket a cikkeket mindaddig közzéteszik, amíg a javasolt specifikációmódosításokat nem véglegesítik, és be nem építik a jelenlegi ECMA-specifikációba.

A szolgáltatás specifikációja és a befejezett implementáció között eltérések lehetnek. Ezeket a különbségeket a vonatkozó nyelvi tervezési értekezlet (LDM) megjegyzései rögzítik.

A funkcióspektusok C# nyelvi szabványba való bevezetésének folyamatáról a specifikációkcímű cikkben olvashat bővebben.

Bajnoki probléma: https://github.com/dotnet/csharplang/issues/4682

Összefoglalás

A C# aláíratlan jobbra tolás operátort támogat beépített operátorként (primitív integráltípusok esetén) és felhasználó által definiált operátorként is.

Motiváció

Az aláírt integrálérték használatakor nem ritka, hogy a biteket jobbra kell áthelyeznie anélkül, hogy minden műszakban replikálja a nagy sorrendű bitet. Ez a primitív integráltípusok esetében egyszerű biteltolási operátorral érhető el, a shift művelet előtt egy előjel nélküli típussá alakításra, majd utána visszaalakításra van szükség. A kódtárak által elérhetővé tenni tervezett általános matematikai felületek kontextusában ez valószínűleg problémásabb, mivel előfordulhat, hogy a típushoz nem szükséges az általános matematikai kód által előre definiált vagy előre ismert, aláíratlan megfelelője, de az algoritmusok egy nem aláírt jobb műszakos művelet végrehajtására is támaszkodhatnak.

Részletes kialakítás

Operátorok és elválasztójelek

A 6.4.6. szakasz úgy lesz módosítva, hogy az >>> operátort – az alá nem írt jobb műszak operátort – tartalmazza:

unsigned_right_shift
    : '>>>'
    ;

unsigned_right_shift_assignment
    : '>>>='
    ;

A unsigned_right_shift és a unsigned_right_shift_assignment produkciókban semmilyen karakter (még a szóköz sem) nem engedélyezett. Ezeket a termeléseket azért kezelik kifejezetten, hogy lehetővé tegyék a type_parameter_listmegfelelő kezelését.

Eltolási operátorok

A 12.11. szakasz úgy lesz módosítva, hogy az >>> operátort – az alá nem írt jobb műszak operátort – tartalmazza:

A <<, >> és >>> operátorok bitváltó műveletek végrehajtására szolgálnak.

shift_expression
    : additive_expression
    | shift_expression '<<' additive_expression
    | shift_expression right_shift additive_expression
    | shift_expression unsigned_right_shift additive_expression
    ;

Az űrlap x << count, x >> count vagy x >>> countművelete esetén a bináris operátorok túlterhelésének feloldása (12.4.5.. §) alkalmazható egy adott operátor-implementáció kiválasztására. Az operandusok a kiválasztott operátor paramétertípusaiká lesznek konvertálva, az eredmény típusa pedig az operátor visszatérési típusa.

Az előre definiált nem aláírt műszakkezelők ugyanazokat az aláírásokat támogatják, amelyeket az előre definiált aláírt műszak-operátorok támogatnak a jelenlegi implementációban.

  • Jobbra váltás:

    int operator >>>(int x, int count);
    uint operator >>>(uint x, int count);
    long operator >>>(long x, int count);
    ulong operator >>>(ulong x, int count);
    nint operator >>>(nint x, int count);
    nuint operator >>>(nuint x, int count);
    

    A >>> operátor az alábbiak szerint kiszámított bitek számával eltolja x-et jobbra.

    A x alacsonyrendű bitjei el lesznek vetve, a fennmaradó bitek jobbra vannak tolva, a nagy sorrendű üres bitpozíciók pedig nullára vannak állítva.

Az előre definiált operátorok esetében az eltolandó bitek száma a következőképpen lesz kiszámítva:

  • Ha a x típusa int vagy uint, a műszakok számát az alacsony sorrendű öt bit countadja meg . Más szóval, a műszakok száma a count & 0x1Falapján kerül kiszámításra.
  • Ha a x típusa long vagy ulong, a műszakok számát a countkisrendű hat bitje adja meg. Más szóval, a műszakok száma a count & 0x3Falapján kerül kiszámításra.

Ha az eredményül kapott műszakszám nulla, a műszak operátorai egyszerűen visszaadják a xértékét.

Az eltolási műveletek soha nem okoznak túlcsordulást, és ugyanazokat az eredményeket adják a checked és unchecked környezetben.

Hozzárendelési operátorok

A szakasz a 12.21 § a következőképpen módosul, hogy tartalmazza az unsigned_right_shift_assignment:

assignment_operator
    : '='
    | '+='
    | '-='
    | '*='
    | '/='
    | '%='
    | '&='
    | '|='
    | '^='
    | '<<='
    | right_shift_assignment
    | unsigned_right_shift_assignment
    ;

Integráltípusok

Az integráltípusok szakasz 8.3.6 módosítva lesz, hogy tartalmazza a >>> operátorra vonatkozó információkat. A vonatkozó listajel a következő:

  • A bináris <<, >> és >>> operátorok esetében a bal operandus Ttípussá alakul, ahol a T az első int, uint, longés ulong, amely teljes mértékben képes az operandus összes lehetséges értékének megjelenítésére. A művelet ezután a Ttípus pontosságával történik, és az eredmény típusa T.

Állandó kifejezések

A >>> operátort hozzáadják azon konstruktumok halmazához, amelyek megengedettek a konstans kifejezésekben a §12.23szakaszban.

Operátor túlterhelése

Az >>> operátort hozzáadják a túlterhelhető bináris operátorok halmazához a szakasz §12.4.3alatt.

Kiterjesztett operátorok

Az operátor >>> hozzáadódik a bináris operátorok köréhez, lehetővé téve egy emelt formát a §12.4.8résznél.

Operátorok elsőbbsége és asszociativitása

A 12.4.2. szakasz úgy lesz módosítva, hogy >>> operátort a "Shift" kategóriához, >>>= operátort pedig a "Hozzárendelés és lambda kifejezés" kategóriához adja hozzá.

Nyelvtani kétértelműségek

A >>> operátorra ugyanazok a nyelvtani kétértelműségek vonatkoznak, amelyek §6.2.5 mint normál >> operátorra vonatkoznak.

Operátorok

A §15.10 szakasz úgy lesz módosítva, hogy >>> operátort is tartalmazza.

overloadable_binary_operator
    : '+'   | '-'   | '*'   | '/'   | '%'   | '&'   | '|'   | '^'   | '<<'
    | right_shift | unsigned_right_shift | '=='  | '!='  | '>'   | '<'   | '>='  | '<='
    ;

Bináris operátorok

Az >>> operátor aláírására ugyanazok a szabályok vonatkoznak, mint a 15.10.3>>.

Metaadat neve

Az ECMA-335 "I.10.3.2 Bináris operátorok" szakasza már fenntartotta egy nem aláírt jobb műszak operátor nevét – op_UnsignedRightShift.

Linq-kifejezésfák

Az >>> operátor nem támogatott a Linq Kifejezésfáiban, mert az aláírt típusok előre definiált >>> operátorainak szemantikája nem jeleníthető meg pontosan anélkül, hogy átalakításokat adnál egy aláíratlan típushoz és vissza. További információért lásd a https://github.com/dotnet/csharplang/blob/main/meetings/2022/LDM-2022-02-09.md#unsigned-right-shift-operator jelű részt.

Dinamikus kötés

Úgy tűnik, hogy a dinamikus kötés a System.Linq.Expressions.ExpressionType enum értékeit használja a bináris operátor típusának a futtatókörnyezeti kötéssel való kommunikációhoz. Mivel nincs olyan tagunk, amely kifejezetten egy nem aláírt jobb műszakos operátort képviselné, >>> operátor dinamikus kötése nem támogatott, és a statikus és a dinamikus kötés (§12.3) szakasz ennek megfelelően lesz módosítva.

Hátránya

Alternatívák

Linq-kifejezésfák

A >>> operátort a Linq Expressioin Trees támogatja.

  • Felhasználó által definiált operátor esetén létrejön egy, az operátor metódusára mutató BinaryExpression csomópont.
  • Előre definiált operátorok esetén
    • ha az első operandus egy előjeles típus, létrejön egy BinaryExpression csomópont.
    • Ha az első operandus előjeles típus, az első operandus előjelnélküli típusra lesz konvertálva, létrejön egy BinaryExpression csomópont, és az eredmény konvertálása vissza az előjeles típusra hozzáadásra kerül.

Például:

Expression<System.Func<int, int, int>> z = (x, y) => x >>> y; // (x, y) => Convert((Convert(x, UInt32) >> y), Int32)

Resolution:

Elutasítva, további információért lásd: https://github.com/dotnet/csharplang/blob/main/meetings/2022/LDM-2022-02-09.md#unsigned-right-shift-operator.

Megoldatlan kérdések

Tervezési találkozók

https://github.com/dotnet/csharplang/blob/main/meetings/2022/LDM-2022-02-09.md