Почему некоторые типы не имеют буквенных модификаторов

Например, почему long int имеет буквенный модификатор, но короткий int не делает? Я имею в виду следующий вопрос на этом сайте: литералы номер компилятора C #

В целом, C #, кажется, очень хорошо продуманный и последовательный язык. Вероятно, есть веская причина для предоставления литературных модификаторов для некоторых типов, но не для всех. Что это?

Почему long int имеет буквенный модификатор, но короткий int не делает?

Вопрос: «Почему C # не имеет этой функции?» Ответ на этот вопрос всегда один и тот же. По умолчанию функции не реализованы; У C # эта функция отсутствует, потому что никто не проектировал, не реализовал и не отправил эту функцию клиентам.

Отсутствие функции не нуждается в обосновании. Скорее, все функции должны быть оправданы, показывая, что их преимущества перевешивают их затраты. Как человек, предлагающий эту функцию, бремя ответственности за то, что вы считаете, что функция ценна; бремя не на меня объясняет, почему это не так.

Вероятно, есть веская причина для предоставления литературных модификаторов для некоторых типов, но не для всех. Что это?

Теперь это более спорный вопрос. Теперь вопрос заключается в том, «что оправдывает буквальный суффикс на долгое время, и почему это не является оправданием для аналогичного суффикса буквального текста на коротком этапе?»

Целые числа могут использоваться для различных целей. Вы можете использовать их как арифметические числа . Вы можете использовать их как коллекции бит-флагов . Вы можете использовать их как индексы в массивы. И есть еще много специальных назначений. Но я считаю справедливым сказать, что большую часть времени целые числа используются как арифметические числа.

Подавляющее большинство вычислений, выполняемых в целых числах по нормальным программам, include числа, которые намного меньше, чем диапазон 32-разрядного целого числа со знаком – примерно +/- два миллиарда. И многие современные аппаратные средства чрезвычайно эффективны при работе с 32-битными целыми числами. Поэтому имеет смысл сделать стандартное представление чисел для подписи 32-битными целыми числами. Поэтому C # сконструирован таким образом, чтобы вычисления, состоящие из 32-битных целых чисел со знаком, выглядели совершенно нормально; когда вы говорите «x = x + 1», что «1» понимается как подписанное 32-битное целое число, и коэффициенты хороши, что x тоже, и результат суммы тоже.

Что делать, если вычисление является интегральным, но не вписывается в диапазон 32-битного целого? «длинные» 64-битные целые числа являются разумным следующим шагом; они также эффективны на множестве аппаратных средств, а longs имеют диапазон, который должен удовлетворять потребностям почти всех, кто не делает сверхмощную комбинаторика, которая включает в себя очень большие числа. Поэтому имеет смысл иметь некоторый способ четко и кратко указать в исходном коде, что этот литерал здесь следует рассматривать как длинное целое число.

Сценарии взаимодействия или сценарии, в которых целые числа используются как битовые поля, часто требуют использования целых чисел без знака. Опять же, имеет смысл иметь способ четко и кратко указать, что этот литерал предназначен для обработки как целое число без знака.

Итак, суммируя, когда вы видите «1», шансы хороши тем, что в большинстве случаев пользователь намеревается использовать его как 32-битное целое число со знаком. Следующими наиболее вероятными случаями являются то, что пользователь намеревается, чтобы это было длинное целое число или unsigned int или unsigned long. Поэтому для каждого из этих случаев имеются сжатые суффиксы.

Таким образом, эта функция оправдана.

Почему это не оправдание шорт?

Потому что во-первых, в каждом контексте, в котором короткий является законным, уже законно использовать целочисленный литерал. “short x = 1;” совершенно законна; компилятор понимает, что целое число вписывается в короткий и позволяет использовать его.

Во-вторых, арифметика никогда не выполняется в шортах на C # . Арифметика может выполняться в ints, uints, longs и ulongs, но арифметика никогда не делается в шортах. Шорты продвигают к int, и арифметика выполняется в ints, потому что, как я уже говорил, подавляющее большинство арифметических вычислений вписывается в int . Подавляющее большинство не вписывается в короткий. Короткая арифметика, возможно, медленнее на современном оборудовании, которое оптимизировано для ints, а короткая арифметика не занимает меньше места; это будет сделано в ints или longs на чипе.

Вы хотите «длинный» суффикс, чтобы сообщить компилятору «эта арифметика должна быть выполнена в longs», но «короткий» суффикс не говорит компилятору «эта арифметика должна выполняться в шортах», потому что это просто не особенность язык C # для начала.

Причины предоставления длинного суффикса и синтаксиса без знака не относятся к шортам. Если вы считаете, что в этой функции есть неотразимая выгода, укажите, какая польза. Без выгоды, чтобы оправдать свои затраты, эта функция не будет реализована на C #.

Согласно MSDN :

short x = 32767; 

В предыдущем объявлении целочисленный литерал 32767 неявно преобразован из int в короткий. Если целочисленный литерал не помещается в короткое место хранения, произойдет ошибка компиляции.

Таким образом, это функция времени компиляции. short не имеет суффикса, потому что он никогда не понадобится.

Связанный с этим вопрос, вероятно, таков: почему у long , float и decimal есть суффиксы?
И короткий ответ заключался бы в том, что i + 1 и i + 1L могут производить разные значения и, следовательно, разных типов.

Но не существует такой вещи, как «короткая арифметика», short значения всегда преобразуются в int при использовании в расчете.

Как отмечает Эрик в комментарии, мой ответ ниже не имеет смысла. Я думаю, что правильнее сказать, что невозможность выразить короткий литерал в C # и невозможность выразить короткий литерал в IL имеют общую причину (отсутствие убедительной причины для этой функции.) У VB.Net, по-видимому, есть короткий литеральный спецификатор, который интересен (для обратной совместимости с синтаксисом VB?) В любом случае, я оставил здесь ответ, поскольку некоторая информация может быть интересной, даже если аргументация неверна.


Нет короткого литерала, потому что на самом деле нет никакого способа, чтобы короткий литерал загружался в IL, базовый язык, используемый CLR. Это связано с тем, что все «короткие» типы (что-то меньшее, чем int) неявно расширяются до int при загрузке в стек операций. Подписанные и неподписанные также являются операциями, а не фактически «сохраненными» с активным числом в стеке операций. «Короткие» типы вступают в игру только тогда, когда вы хотите сохранить число в стеке операций в ячейке памяти, поэтому есть операции ИИ для преобразования в различные «короткие» типы (хотя на самом деле он все еще расширяет число обратно к int после преобразования, он просто гарантирует, что значение будет пригодно для хранения в поле «короткого» типа.)

С другой стороны, длинные типы имеют спецификатор букв, из-за того, что они обрабатываются по-разному в стеке операций. Для загрузки константных длинных значений существует отдельная инструкция Ldc_I8. Есть также Ldc_R4 (следовательно, для чего вам нужно «f» для float) и Ldc_R8 (C # выбирает это, поскольку он используется по умолчанию, если вы используете десятичное число без спецификатора.) Десятичное значение является частным случаем, поскольку на самом деле это не примитивный тип в IL ; он просто имеет встроенный константный указатель «m» в C #, который компилируется в вызов конструктора.

Что касается того, почему нет специальных коротких операций (и соответствующих коротких литералов), это, скорее всего, потому, что большинство современных архитектур процессоров не работают с регистрами размером меньше 32 бит, поэтому на уровне ЦП не стоит различать. Вы могли бы сохранить размер кода (в байтах ИЛ), допустив «короткие» нагрузки IL-кодов, но за счет дополнительной сложности для джиттера; сохраненное пространство кода, вероятно, не стоит.

Поскольку short может быть неявно преобразован в int , long , float , double или decimal ; нет необходимости в модификаторе букв.

Рассматривать:

 void method(int a) {} void method2() { short a = 4; method(a); // no problems } 

Вы можете заметить, что char и byte также имеют буквенные модификаторы, возможно, по той же причине.

 From To sbyte short, int, long, float, double, or decimal byte short, ushort, int, uint, long, ulong, float, double, or decimal short int, long, float, double, or decimal ushort int, uint, long, ulong, float, double, or decimal int long, float, double, or decimal uint long, ulong, float, double, or decimal long float, double, or decimal char ushort, int, uint, long, ulong, float, double, or decimal float double ulong float, double, or decimal 

Если вы объявите буквальный короткий и сделаете его больше, чем Short.MaxValue ошибка компилятора, иначе литерал будет коротким.

Время, в течение которого я работал в Short, было для значений, которые хранятся в базе данных.

Они представляют собой положительные целочисленные значения, которые редко будут превышать 10-20 (байт или сбайт будет достаточно большим, но я решил, что чуть-чуть убил бы меня от сожаления по моему выбору, если бы код был повторно использован несколько иначе)

Поле используется, чтобы пользователь сортировал записи в таблице. В этой таблице отображается раскрывающийся список или список переключателей, которые упорядочиваются по «времени» (первый шаг, шаг 2, …).

Будучи новичком в C # (и достаточно старым, чтобы помнить, когда подсчитывали байты), я подумал, что это будет немного более эффективно. Я не занимаюсь математикой по ценностям. Я просто сортирую их (и меняю их между записями). Единственной математикой до сих пор была «MaxInUse» +1 (для новых записей), которая является специальным случаем «++ MaxInUse». Это хорошо, потому что отсутствие литерала означает «s = s + 2» должно быть «s = (Int16) (s + 2)».

Теперь, когда я вижу, как раздражает C #, работает с другими ints, я ожидаю присоединиться к современному миру и потерять байты, JUST, чтобы сделать компилятор счастливым.

Но не следует ли «сделать компилятор счастливым» ранг около 65 в наших топ-10 целей программирования?

Является ли еще лучше, чтобы компилятор жаловался на добавление целого числа «2» к любому из типов INTEGER? Он должен жаловаться на «s = 123456», но это другой случай.

Если кто-то должен иметь дело с математикой и шортами, я предлагаю вам сделать свои собственные литералы. (Сколько вам нужно?)

 short s1= 1, s2 = 2, s123 = 123; 

Тогда s = s + s2 лишь немного раздражает (и запутывает для тех, кто следит за вами).

  • Что означает символ M в десятичной литературе C #?
  • Что префикс @ делает для строковых литералов в C #?
  • Java: как мне получить литерал classа из общего типа?
  • Тип целочисленных литералов не int по умолчанию?
  • Установка короткого значения Java
  • Должны ли мы обычно использовать float-литералы для поплавков вместо простых двойных литералов?
  • Неожиданное сохранение данных
  • Давайте будем гением компьютера.