Можно ли сделать const&
действительно неизменным?
int* side_effect;
void function(int const& i){
*side_effect = 123;
}
int main(){
int i = 0;
side_effect = &i;
//based on the function signature, i is suspected not to change.
//however, that is not the case.
function(i);
}
Существуют ли какие-либо предупреждения компилятора, атрибуты, расширения компилятора или языковые функции, которые я могу использовать, чтобы избежать подобных проблем?
Если вы хотите, чтобы значение было истинной константой, вы можете передать его в качестве аргумента значения шаблона.
template<int i>
void function(){
*side_effect = 123;
}
нет никакой возможности для какой-либо операции изменить i
,
Это требует, чтобы входные данные были константой времени компиляции (и это проверялось компилятором во время компиляции).
Так что это не работает:
int main(){
int i = 0;
side_effect = &i;
function<i>();
}
как i
не является константой времени компиляции. Если бы мы вместо этого сделали это:
int main(){
const int i = 0;
side_effect = &i;
function<i>();
}
function<i>
линия работает, но side_effect = &i
не работает Если мы добавим в актерский состав:
int main(){
const int i = 0;
side_effect = const_cast<int*>(&i);
function<i>();
}
сейчас операция *side_effect = 123
становится UB в течение function
,
Другой подход, который не требует, чтобы передаваемое значение было истинной константой времени компиляции, состоит в том, чтобы не брать ссылку:
void function(int i){
*side_effect = 123;
}
и вместо этого возьмите локальную копию (либо int
или же const int
в качестве аргумента, в зависимости от того, если мы хотим function
иметь право изменять i
).
Полная версия того, что вы хотите — мы берем ссылку на внешние данные, а затем гарантируем, что внешние данные остаются неизменными, — можно довольно легко показать как эквивалентную проблеме остановки в общем случае.
Других решений пока нет …