Здравствуйте, Zhendos, Вы писали:
Z>Так пусть foo меняет что угодно в пределах элемента и полностью игнорирует const, Z>на как изменение элемента влияет на размер основного вектора, почему-то он-то может поменяеться?
Здравствуйте, koenjihyakkei, Вы писали:
K>Здравствуйте, Zhendos, Вы писали:
Z>>Спасибо. Пометил функцию как неработающую с глобальными переменными и компилятор тут же начал генерировать Z>>нормальнй код.
K>А это как?
В gcc и clang — __attribute__((const))
Re: Что мешает не вычислять size() каждую итерацию цикла?
Здравствуйте, Zhendos, Вы писали:
Z>Почему код ниже превращается в ассебмлер, где каждую итерацию цикла Z>"size" перевычисляется? Грубо говоря "foo" получает "MyVec<int> *", Z>почему компилятор считает что "MyVec<MyVec<int>>" может из-за этого поменяться?
Мешает передача в функцию по ссылке, скорее всего, т.к. компилятор думает что снаружи вектор может поменяться. Вот так — уже не думает.
Re[3]: Что мешает не вычислять size() каждую итерацию цикла?
Здравствуйте, Zhendos, Вы писали:
Z>Ну и пусть "foo" поменяет элемент типа "MyVec<int>" полностью, Z>причем здесь MyVec<MyVec<int>>, ссылка ведь передается на "MyVec<int>", Z>главный то вектор к этому каким боком и как изменение его элемента может изменить размер самого вектора?
Внутри foo может выполняться вставка или удаление, что изменит размер вектора. Да что там вставка и удаление, полнотью может измениться все его содержимое. И если компилер в точке обращения к foo не видит ее определения, он не может исключать такую возможность.
Здравствуйте, Zhendos, Вы писали:
Z>Почему код ниже превращается в ассебмлер, где каждую итерацию цикла Z>"size" перевычисляется? Грубо говоря "foo" получает "MyVec<int> *", Z>почему компилятор считает что "MyVec<MyVec<int>>" может из-за этого поменяться?
Потому, что foo потенциально может добраться до вектора по глобальной ссылке, которую компилятор не видит, но подозревает, что она есть.
Re: Что мешает не вычислять size() каждую итерацию цикла?
Почему код ниже превращается в ассебмлер, где каждую итерацию цикла
"size" перевычисляется? Грубо говоря "foo" получает "MyVec<int> *",
почему компилятор считает что "MyVec<MyVec<int>>" может из-за этого поменяться?
Здравствуйте, Zhendos, Вы писали:
Z>Почему код ниже превращается в ассебмлер, где каждую итерацию цикла Z>"size" перевычисляется? Грубо говоря "foo" получает "MyVec<int> *", Z>почему компилятор считает что "MyVec<MyVec<int>>" может из-за этого поменяться?
То, что foo обещает не менять один из элементов in вовсе не значит, что она обещает не менять то, на что ссылается in, например получив внутри другую, уже неконстантную ссылку на этот же объект. Компилятор этого не видит и предполагает худшее.
Re: Что мешает не вычислять size() каждую итерацию цикла?
Здравствуйте, Zhendos, Вы писали:
Z>почему компилятор считает что "MyVec<MyVec<int>>" может из-за этого поменяться?
Потому, что константность ссылки, по которой вектор передается в foo, не гарантирует его неизменяемости. Да, взлом константности не есть хорошо с точки зрения дизайна, но программа-то остается well-formed, тем не менее. А значит, компилер обязан корректно обработать и этот случай.
Да и сколько там тех вычислений. Два mov-а и один sub. Неужто чувствительно?
Здравствуйте, rg45, Вы писали:
R>Потому, что константность ссылки, по которой вектор передается в foo, не гарантирует его неизменяемости. Да, взлом константности не есть хорошо с точки зрения дизайна, но программа-то остается well-formed, тем не менее. А значит, компилер обязан корректно обработать и этот случай.
Ну и пусть "foo" поменяет элемент типа "MyVec<int>" полностью,
причем здесь MyVec<MyVec<int>>, ссылка ведь передается на "MyVec<int>",
главный то вектор к этому каким боком и как изменение его элемента может изменить размер самого вектора?
Re[2]: Что мешает не вычислять size() каждую итерацию цикла?
Здравствуйте, andyp, Вы писали:
A>Здравствуйте, Zhendos, Вы писали:
A>То, что foo обещает не менять один из элементов in вовсе не значит, что она обещает не менять то, на что ссылается in, например получив внутри другую, уже неконстантную ссылку на этот же объект. Компилятор этого не видит и предполагает худшее.
Так пусть foo меняет что угодно в пределах элемента и полностью игнорирует const,
на как изменение элемента влияет на размер основного вектора, почему-то он-то может поменяеться?
Re[4]: Что мешает не вычислять size() каждую итерацию цикла?
Здравствуйте, rg45, Вы писали:
R>Здравствуйте, Zhendos, Вы писали:
R>Внутри foo может выполняться вставка или удаление, что изменит размер вектора. Да что там вставка и удаление, полнотью может измениться все его содержимое. И если компилер в точке обращения к foo не видит ее определения, он не может исключать такую возможность.
Да пусть там что угодно выполняется, как это на основной вектор та влияет?
У меня в пример MyVec<MyVec<int>>, а в foo передается просто MyVec<int>,
пусть MyVec<int> как угодно поменяется, вычисляется то ведь MyVec<MyVec<int>>::size,
то есть длина совершенно другого вектора.
Re[3]: Что мешает не вычислять size() каждую итерацию цикла?
Здравствуйте, Zhendos, Вы писали:
Z>Так пусть foo меняет что угодно в пределах элемента и полностью игнорирует const, Z>на как изменение элемента влияет на размер основного вектора, почему-то он-то может поменяеться?
Что значит пусть? Вообще-то foo может менять всё, кроме этого элемента, если он const Никто ж не может обещать, что она будет использовать только то, с чем ты ее вызвал.
Re[5]: Что мешает не вычислять size() каждую итерацию цикла?
Здравствуйте, Zhendos, Вы писали:
Z>У меня в пример MyVec<MyVec<int>>, а в foo передается просто MyVec<int>,
Фу, блин, только сейчас досмотрелся, что у тебя там вектор в векторе. Виноват, не досмотрелся.
Но даже таком случае у компилятора нет достаточных оснований считать, что внешний вектор не изменяется внутри foo. А раз так, то и оптимизацию вычислений он применить не может.
--
Re[5]: Что мешает не вычислять size() каждую итерацию цикла?
Здравствуйте, Zhendos, Вы писали:
Z>Да пусть там что угодно выполняется, как это на основной вектор та влияет?
Да не в этом дело. У тебя функция `foo` может сделать с твоим вектором что угодно в принципе. Ей совершенно необязательно для этого использовать параметр, переданный по константной ссылке. В простейшем случае, оригинальный вектор может быть глобальным объектом, который foo меняет в свое удовольствие напрямую, игнорируя аргумент.
Да здравствует мыло душистое и веревка пушистая.
Re[4]: Что мешает не вычислять size() каждую итерацию цикла?
Здравствуйте, Zhendos, Вы писали:
Z>Спасибо. Пометил функцию как неработающую с глобальными переменными и компилятор тут же начал генерировать Z>нормальнй код.