Подскажите, пожалуйста, возникает ли в следующем случае неопределенное поведение:
void do_something(const Object& _1,
const Object& _2,
Object& _3)
{
// ...
for (size_t i = 0; i < ...; ++i)
{
const auto value = _1[i] + _2[i];
_3[i] = value;
}
}
int main(int argc, char **argv)
{
Object _1;
Object _2;
do_something(_1, _2, _1);
return 0;
}
С одной стороны, здесь нет нарушения Правила Строгих Псевдонимов
.
Но с другой стороны, внутри функции do_something()
мы меняем состояние внешнего объекта, на который ссылается функция, как на константный.
Мой код ведет себя странно.
Причем, если я сделаю так:
int main(int argc, char **argv)
{
Object _1;
Object _2;
Object _3;
do_something(_1, _2, _3);
return 0;
}
То проблема исчезает.
Если в коде ваши обьекты верно инициализированы(в функции нет выхода за пределы последовательностей, то не будет никакого неопределенного поведения. В данном случаи константными являются только аргументы функции, а передаваемые ей обьекты вполне могут быть неконстантными. Константность аргументов говорит о том, что функция не модифицирует первые два аргумента. Но третьим аргументом может выступать любой передаваемый неконстантный обьект, в том числе и один из двух переданных обьектов.
P.S. Вот какой код выполняется у вас:
int main(int argc, char **argv)
{
Object a;
Object b;
{
const Object& _1 = a;
const Object& _2 = b;
Object& _3 = a;
// ...
for (size_t i = 0; i < ...; ++i)
{
const auto value = _1[i] + _2[i];
_3[i] = value;
}
} //конец функции
return 0;
}
обьект можно без проблем модифицировать через ссыльку _3
Если какой-то объект виден через константный путь доступа, это совсем не означает, что он не может меняться. Он может меняться через другие, неконстантные пути доступа. Именно это и происходит у вас в коде. Никакого неопределенного поведения в этом нет даже отдаленно.
Компилятор никогда не будет делать никаких оптимизаций на основе константности пути доступа, если у него нет стопроцентной уверенности в том, что объект не может поменяться через другие пути доступа. В языке С вы можете придать ему такую уверенность вручную, при помощи спецификатора restrict
. В С++ такого спецификатора официально нет.
Зачем вы вынесли упоминание "правила строгих псевдонимов" в заголовок - не ясно тоже. Никакого отношения к "правилу строгих псевдонимов" данная ситуация не имеет.
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Написала функцию, но она меняет числа посимвольно =(
Попробовал так, но не получил адекватных значений