Если объект объявлен const
, реализация может хранить его таким образом, что попытки изменить его могут вызвать аппаратные ловушки, без каких-либо обязательств по обеспечению какого-либо конкретного поведения для этих ловушек. Если создать указатель const
на такой объект, получателям этого указателя, как правило, не будет разрешено его записать, и, таким образом, не возникнет опасность запуска этих аппаратных ловушек. Если код отбрасывает const
-несс и записывает в указатель, компилятор не обязан защищать программиста от любых аппаратных сбоев, которые могут возникнуть.
Кроме того, если компилятор может сказать, что объект const
всегда будет содержать определенную последовательность байтов, он может сообщить об этом компоновщику и позволить компоновщику увидеть, происходит ли эта последовательность байтов. где-нибудь в коде и, если это так, рассматривайте адрес объекта const
как местоположение этой последовательности байтов (соблюдение различных ограничений для различных объектов, имеющих уникальные адреса, может быть немного сложнее, но это будет допустимо) , Если компилятор сказал компоновщику, что const char[4]
всегда должен содержать последовательность байтов, которые, как оказалось, появляются в скомпилированном коде для некоторой функции, компоновщик может назначить этой переменной адрес в коде, где появляется эта последовательность байтов. Если const
никогда не записывалось, такое поведение спасло бы четыре байта, но запись в const
произвольно изменила бы значение другого кода.
Если запись в объект после отбрасывания const
всегда была UB, способность отбрасывать константу была бы не очень полезна. Как таковая, способность часто играет роль в ситуациях, когда часть кода удерживает указатели - некоторые из которых const
, а некоторые из них необходимо будет написать - в пользу другого кода . Если при отбрасывании константности const
указателей на объекты, не являющиеся const
, не определено поведение, код, содержащий указатели, должен знать, какие указатели являются const
, а какие нужно записать , Однако, поскольку приведение к константам разрешено, для кода, содержащего указатели, достаточно объявить их все как const
, а для кода, который знает, что указатель идентифицирует неконстантный объект и хочет его записать, для его приведения на не приведенный указатель.
Возможно, было бы полезно, если бы в C ++ были формы квалификаторов const
(и volatile
), которые можно использовать в указателях для указания компилятору, что он может (или, в случае volatile
, должен) учитывать указатель, идентифицирующий const
и / или volatile
объект , даже если компилятор знает, что это объект, и знает, что он не const
и / или не объявлен volatile
, Первый позволил бы компилятору предположить, что объект, идентифицированный указателем, не изменится в течение времени существования указателя, и кешировать данные на его основе; последний учел бы случаи, когда переменная может нуждаться в поддержке volatile
доступа в некоторых редких ситуациях (обычно при запуске программы), но когда компилятор должен иметь возможность кэшировать свое значение после этого. Однако я не знаю предложений по добавлению таких функций.