Почему массивы Pascal const не являются константами?

  Program ConstTest;
  Const constVar = 1;
  Begin
    constVar := 3;
    WriteLn(constVar);
  End.

Довольно очевидно, что вышеприведенный код не будет компилироваться, потому что это не так, чтобы изменить значение константы. Однако следующий код будет компилироваться и будет возвращать "1; 5; 3;", хотя массив является константой:

Program ConstTest;
  Const constArr:Array [1..3] Of ShortInt = (1,2,3);
  Var i:ShortInt;
  Begin
    constArr[2] := 5;
    For i:=1 To 3 Do WriteLn(constArr[i],'; ');
  End.

Итак, что вызывает такое поведение? Почему константа не является константой?

Я использую FreePascal Compiler 2.2.0 для Win32.

Ответ 1

У вас есть типизированная константа. Типированные константы отличаются от обычных констант (константы истины a.k.a), что и есть ваш constVar. Обратите внимание, как вам не нужно было указывать тип на constVar; если бы у вас было, вы можете увидеть, что компилятор также позволяет вам присваивать ему новые значения:

const
  constVar: Integer = 1;

Руководство Free Pascal описывает типизированные константы:

В отличие от обычных констант, значение может быть присвоено им во время выполнения. Это старая концепция от Turbo Pascal, которая была заменена поддержкой инициализированных переменных: Подробное описание см. В разделе 4.4, страница 183.

Поддержка присвоения значений типизированным константам управляется директивой {$J}: ее можно отключить, но она включена по умолчанию (для совместимости с Turbo Pascal). Инициализированные переменные всегда разрешены.

Для инициализированной переменной замените const на var в объявлении. Он получит свою ценность при вводе области. Или отключите директиву $J до объявления с типизированной константой:

{$J-}
const
  constArr: array [1..3] of ShortInt = (1, 2, 3);
{$J+}

Если вы вернете его обратно, это зависит от вас.


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

Ответ 2

Хорошо, если вы также знаете C, вот несколько аналогов:

В [Turbo/Free] Pascal записывайте что-то вроде этого:

const
     MIN = 5;
     MAX = 10;

Это эквивалентно выполнению этого в C:

#define MIN 5
#define MAX 10

То есть, символ времени компиляции заменяется, как говорит другой плакат.

С записями и массивами (типизированные константы) выражение "const" является всего лишь способом инициализации блока памяти, связанного с символом линкера.

TODO: встречный пример.