Zorko писал(а):
И я уверен, что CONST a = LONG(LONG(0)) здесь не поможет.
Действительно, тип константы определяется ее значением. Так числовая константа в какой наименьший тип влезла, такого типа она и есть. Вместо константы-литерала везде можно использовать константное выражение, но после вычисления такого выражения получается число. И тип выражения определяется этим числом, как если бы оно было изначально задано. Так что,
LONG(0) и
0+0 и
0-0*0 дают в результате "0", а значит представляют собой просто другой способ записи "константы ноль".
Вот переменные - другое дело, тут тип определяется не текущим значением, а потенциальными возможностями хранилища. Пусть сейчас там ноль, но ведь может быть и другое значение. Если
VAR x:INTEGER, то выражение
LONG(x) имеет тип LONGINT (даже если х=0 в данный момент).
В ТурбоПаскале были так называемые "типизированные константы", которые по сути были не константами, а переменными. Их можно бы назвать "преинициализированными переменными с глобальным временем жизни".
А вот константа
CONST a = LONGINT(0); больше заслуживает название "типизированная" - это константа у которой есть не только значение, но и особый тип (к значению дополнительно приклеен "ярлык", "тэг" с названием типа). Переменная обязана уметь хранить любое значение своего типа, для чего ей выделена память соответствующего размера. У типизированной константы значение уже задано и не изменится, так что память для всего диапазона значений можно не выделять, но компилятор где-то должен хранить ее тип.
Типизированная константа (настоящая, а не турбопаскалевская) - это некий гибрид между переменной и константой, в большей степени это константа, но на переменную она похожа наличием типа. Введение таких констант в компилятор усложнит вычисление константных выражений. Сейчас выражение из констант сначала вычисляется, а потом по результату определяется его тип. При наличии типизированных констант тип придется вычислять непрерывно, одновременно со значением.
Но это и правда снимет неоднозначности в некоторых случаях, например таким образом можно будет задавать знаковые и беззнаковые константы (когда таковые появятся).
Цитата:
Так что не знаю насколько большой будет доработка Ofront'а. Но, в принципе, если уж разрешать такое прямое уточнения типа константы:
Код: "OBERON"
TYPE TheClocks = ARRAY 10 OF INTEGER;
CONST AnimClockData = TheClocks(
00400, 00070, 00000, 00700, 00100, 00380, 00000, 00700, 03008, 00000);
то будет логично распространить его и на остальные типы независимо от того, много ли случаев неоднозначной трактовки типа констант может случиться. Кстати, насколько я помню, в Active Oberon (и как раз с подачи Патрика Реали) есть возможность задать тип константы. Также (если правильно помню) в AO есть и константные массивы.
А вот константные массивы - это уже нечто другое, чем
LONGINT(0). Потому что, числовые константы были изначально, пусть даже их тип задавался значением, а не явным указанием. А вот массивов-констант какого либо типа не было (за исключением, разве что, цепочек символов). Как они должны толковаться семантически? Как IN-параметры, полученные откуда-то извне? AnimClockData[0] - это константное выражение? Можем ли мы передать такой массив в процедуру фактическим параметром, только ли по значению или как IN тоже можно?
Обычная константа задается только своим значением и это значение собственно сама константа и есть. Типизированная константа кроме значения имеет тип, поэтому INTEGER(0) и LONGINT(0) имеют одинаковое значение и разный тип. Константный массив видимо имеет еще и адрес, который и передается в процедуры.
Цитата:
Ещё, кстати, как быть, разрешать ли такое?
Код: "OBERON"
CONST AnimClockData = ARRAY 10 OF INTEGER(
00400, 00070, 00000, 00700, 00100, 00380, 00000, 00700, 03008, 00000);
А это уже константный массив анонимного типа. Навроде,
Код: "OBERON"
TYPE TheClocks = ARRAY 10 OF INTEGER;
CONST AnimClockData = TheClocks(
00400, 00070, 00000, 00700, 00100, 00380, 00000, 00700, 03008, 00000);
, но идентификатор типа
TheClocks спрятан, так что мы не можем его нигде употребить. Значит не можем задать переменную или параметр такого типа, поэтому не можем получить "Одинаковые типы [Same types]" и значит "эквивалентные типы" тоже не получим и вообще мало что сможем с таким массивом сделать. Если, конечно, не расширим понятия совместимости, как это расширено для строк (именно потому, что строки задаются "константными массивами анонимных типов").
Лучше бы вводить новые фичи постепенно, исходя из практической потребности. Скажем, для начала можно ввести константные массивы неанонимного типа, семантически толкуя их как полученные извне IN-параметры. Это, думаю, будет проще реализовать и пока для практики достаточно.