Подтвердить что ты не робот

Преимущества постоянных

Я понимаю, что одна из больших сделок о константах заключается в том, что вам не нужно проходить и обновлять код, где эта константа используется повсюду. Это здорово, но скажите, что вы явно не объявляете его константой. Какие преимущества существуют, чтобы взять переменную, которая HAPPENS фактически не будет изменена и сделать ее постоянной, будет ли это экономить на обработке и/или размере кода... и т.д.?

В основном у меня есть программа, в которой компилятор говорит, что конкретная переменная не изменяется и, таким образом, может быть объявлена ​​константой, я просто хотел знать, какая польза от добавления к ней постоянного определителя будет, если она не сделает разница в том, что это изменение не добавляет никакого значения и, таким образом, не теряется время (этот же сценарий происходит в более чем одном месте) возвращается и "фиксирует" все эти переменные.

4b9b3361

Ответ 1

Если вы объявляете переменную константой, то оптимизатор часто может ее устранить с помощью "постоянного складывания" и, таким образом, ускорить вашу программу и сэкономить ваше место. В качестве примера рассмотрим следующее:

var int a = 5;
const int b = 7;
...
c = process(a*b);

Компилятор завершит создание команды для умножения на 7 и передаст это процессу, сохраняя результаты в c. Однако в этом случае:

const int a = 5;
const int b = 7;
...
c = process(a*b);

Компилятор просто передаст 35, чтобы обработать, и даже не умножить код. Кроме того, если компилятор знает, что процесс не имеет побочных эффектов (т.е. Простой расчет), то он даже не вызовет процесс. Он просто установит c как возвращаемое значение процесса (35), сохранив вам вызов функции.

Ответ 2

Если вы объявляете что-то как константу, а затем случайно пытаетесь изменить его значение в своем коде, компилятор расскажет вам о вашей ошибке. Эта форма проверки статического типа на самом деле является основной причиной использования констант.

Ответ 3

Многое зависит от того, насколько хорош ваш оптимизатор.

Хороший оптимизатор заменит константные ссылки с буквальными значениями во время компиляции. Это экономит циклы процессора, так как сгенерированный машинный код работает с непосредственными значениями, а не загружает значение из памяти.

Некоторые оптимизаторы узнают, что после объявления не изменяется значение и конвертирует его в константу для вас. Не полагайтесь на это поведение.

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

Ответ 4

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

Ответ 5

Как вы отмечаете, вы не можете получить прямую выгоду от изменения неизменяемых переменных в явные константы. Однако при анализе программы выполняется одна проверка, чтобы посмотреть точку объявления переменной в точку отсчета переменной. Таким образом, такие показатели, как переменные, которые доступны перед объявлением, или набор и reset до ссылки и т.д., Могут указывать на возможные ошибки.

Явным образом объявляя константы в качестве констант, инструменты компилятора и анализаторы знают, что вы не намерены использовать переменную reset в любое время.

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

Ответ 6

Возможно, что компилятор может уменьшить размер кода.. например, в пакете System вы найдете (на машине x86)

type Bit_Order is (High_Order_First, Low_Order_First);
Default_Bit_Order : constant Bit_Order := Low_Order_First;

так что данный

case System.Default_Bit_Order is
   when System.High_Order_First =>
      --  Big-endian processing
   when System.Low_Order_First =>
      --  Little-endian processing
end case;

компилятор может полностью исключить "неправильную" ветвь, в то время как ваш код сохраняет свою мобильность. С GNAT вам нужно использовать оптимизацию по умолчанию, чтобы это произошло: -O2 Я думаю.

Обе ветки должны быть скомпилированы - это оптимизация, а не обработка #ifdef.

Ответ 7

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

Должно быть понятно, какие значения никогда не могут измениться и какие значения могут измениться. Константы усиливают ваши намерения.


Реальный мир из моей юности:

У меня не было встроенного значения PI в системе, над которой я работал, поэтому кто-то создал переменную PI и где-то по пути, кто-то (меня) изменил это значение на 3.14519 (или что-то там о) в процедура, которую я написал... не приближение pi 3.14159). Он был установлен в другом месте в коде, и всевозможные вычисления были отключены с этого момента. Если бы PI был постоянным (это было изменено позже, конечно), я бы не смог сделать эту ошибку... по крайней мере, нелегко.

Ответ 8

В дополнение к тому, что уже было сказано, объявление переменной как константы дает больше свободы для оптимизатора. Он может исключить считывание его значений, он может исключить необходимость создания временной копии, он может устранить сама переменная (это особенно верно для числовых констант).

Другим важным вариантом для констант являются постоянные объекты. Имея постоянный объект (или отдавая ссылку на постоянный объект в функции), вы можете быть уверены, что ваш объект не изменен, и разрешены только методы (называемые const методами) этого объекта. Это, однако, верно для С++, я не уверен, что эта же концепция действительно и в Ada.

Ответ 9

Другая возможность, в зависимости от языка, заключается в том, что компилятор может выполнять некоторые оптимизации в многопоточной среде, которая в противном случае была бы невозможна. Например, если вы скажете:

int b=x*f;
int c=y*f;

В многопоточной среде, если f является переменной, компилятору, возможно, придется создать перезагрузку f до второй операции. Если f является константой, и компилятор знает ее все еще в регистре, ее не нужно перезагружать.

Ответ 10

Конечно, для языка, такого как C и Ada, компилятор будет поместить значение из константы непосредственно в инструкцию ассемблера, что означает, что никакая перестановка регистров или чтение из памяти не потребуются сверх того, что требуется для запуска программы, Это означает две вещи: главная из них - скорость (возможно, не так заметно во многих приложениях, если они не встроены), а вторая - использование памяти (как финального двоичного размера программы, так и ее памяти).

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

Во-вторых, как было указано в его matt и jball, он позволяет логически рассматривать элемент как элемент постоянной конфигурации, а не "переменную"; особенно на языках программирования более высокого уровня и интерпретируемых языках.

Ответ 11

На самом деле это не вопрос, специфичный для Ады.

Общие преимущества констант над переменными:

  • Предотвращает ошибки кода из "константы", которые случайно становятся модифицированными.
  • Сообщает компилятору, что он может предположить, что значение не изменится при оптимизации.

Специальные преимущества Ada:

  • Для числовых констант вам не нужно указывать тип (именованные номера). Если вы объявите его таким образом, он будет использоваться в любом выражении для такого числа. Если вы используете переменную вместо этого, ее можно использовать только в выражениях этой переменной точного типа.

Пример:

Seconds_Per_Minute : constant := 60;
Secs_Per_Min       : Integer  := 60;

type Seconds_Offset is 0 .. Integer'last; --'

Min1, Secs1 : Integer;
Min2, Secs2 : Seconds_Offset;

...
--// Using the named number, both of these compile no problem.
Secs1 := Min1 * Seconds_Per_Minute;
Secs2 :=  Min2 * Seconds_Per_Minute;

--// The second line here gives an error, since Integer is a 
--// different type than Seconds_Offset.
Secs1 := Min1 * Secs_Per_Min;
Secs2 := Min2 * Secs_Per_Min;

Ответ 12

Существует еще одно преимущество, размер сегмента и данных.

Рассмотрим:

function Recurser(i : Integer) return Integer is
  ia : array(0..9) of Integer
          := (1, 2, 3, 4, 5, 6, 7, 8, 9, 1000);
  r : Integer;
begin
   if i = 0 then return 0; end if;
   r := ia(i mod 10);
   return r + Recurser(i - 1);
end;

Каждый раз, когда эта функция рекурсирует, вы создаете структуру 320 байтов в стеке. Но поскольку значение a не изменяется, стек увеличивается, чтобы удерживать переменную, которая является постоянной. Это может быть очень важно на встроенных платформах с небольшими пакетами.

Переменные уровня пакета также увеличивают размер сегмента данных. Наращивание ваших потребностей в памяти.

Ответ 13

Константы обычно хранятся в памяти только для чтения, что предотвращает их изменение во время выполнения, и доступ к ним может быть более быстрым или, по крайней мере, столь же быстрым, как доступ к ОЗУ.

Ответ 14

Константы - это неизменные значения, которые известны во время компиляции и не изменяются для жизни программы.

Константы отличаются от переменных одним существенным образом тем, что после того, как значение было присвоено константе, оно впоследствии не может быть изменено.

Во время выполнения вы можете быть уверены, что значение, определенное в константе, не изменится и, следовательно, ваша программа не сломается.