Как уже упоминалось, приведение удаляет «константность» пункта назначения в том, что касается выражения. Когда вы используете приведение, компилятор обрабатывает выражение в соответствии с приведением - до тех пор, пока приведение само по себе допустимо (и приведение в стиле C в значительной степени является большим молотком). Вот почему вы не получаете сообщение об ошибке или предупреждение. По сути, вы говорите компилятору: «Молчи, я знаю, что делаю, вот как ты должен относиться к вещам». Фактически, приведение - это, вероятно, # 1 способ для программистов заставить компилятор прекратить выдавать предупреждения.
Ваше выражение присваивания может быть или не быть неопределенным поведением. Разрешается выбрасывать константу , если объект, на который фактически указывает, не является константой.
Однако, если объект, на который указывает объект, является const, то у вас неопределенное поведение.
void TestFunc(const void * const Var1, const float Var2)
{
*(float*)Var1 = Var2;
}
int
main(void)
{
float x = 1.0;
const float y = 2.0;
TestFunc( &x, -1.0); // well defined (if not particularly great style)
TestFunc( &y, -2.0); // undefined behavior
return 0;
}
Вы идете по опасным водам ...
В целом (я уверен, что есть исключения), поддерживается приведение, чтобы выражения обрабатывали объекты так, как они есть на самом деле, хорошо определенное поведение в C / C ++.
Это конкретное поведение в стандартах охватывается в основном заявлениями, которые изменяют const-объект посредством преобразования (или чего-либо), удаляющего квалификатор const, не определено. Вывод заключается в том, что выполнение того же для неконстантного объекта не является неопределенным. Пример, приведенный в стандарте C ++, проясняет это.
C90 6.5.3 - Классификаторы типов (C99 6.7.3):
Если предпринята попытка изменить объект, определенный с помощью типа с константой, посредством использования
lvalue с неконстантным типом, поведение не определено.
C ++ 7.1.5.1 Классификаторы cv
Указатель или ссылка на тип с квалификацией cv не обязательно должен указывать или ссылаться на объект с квалификацией cv, но он обрабатывается так, как если бы он был; квалифицированный константный путь доступа не может использоваться для изменения объекта, даже если упомянутый объект является неконстантным объектом и может быть изменен через какой-либо другой путь доступа. [Примечание: cv-квалификаторы
поддерживается системой типов, так что они не могут быть уничтожены без приведения (5.2.11). ]
За исключением того, что любой член класса, объявленный mutable (7.1.1), может быть изменен, любая попытка изменить const
объект в течение его жизни (3.8) приводит к неопределенному поведению.
...
[Пример: * * тысяча тридцать-один
...
int i = 2; //not cv-qualified
const int* cip; //pointer to const int
cip = &i; //OK: cv-qualified access path to unqualified
*cip = 4; //ill-formed: attempt to modify through ptr to const
int* ip;
ip = const_cast<int*>(cip); //cast needed to convert const int*to int*
*ip = 4; //defined: *ip points to i, a non-const object
const int* ciq = new const int (3); //initialized as required
int* iq = const_cast<int*>(ciq); //cast required
*iq = 4; //undefined: modifies a const object