Pull to refresh

Comments 24

а еще можно помечать данные constexpr и есть шанс, что они вообще не будут созданы в памяти
Иногда можно, а иногда и нельзя. Вот что автор оригинальной статьи пишет по этому поводу:
I love constexpr and it bothers me that the C++ committee designed in such a way that I often cannot use it. Look at the change in https://codereview.chromium.org/2608823002 for example – in that example a const array is defined in one translation unit and use in another. constexpr does not support that. You cannot go “extern constexpr”.

The reason why is because constexpr means “available at compile time” even though I often wish that it meant “generated at compile time”. There is no way in C++ to require that something be generated at compile time without requiring that it be available at compile time, so enforcing my wishes for these arrays is, in general, impossible.

That said, there are some places where I could have used constexpr. I think I tried that and hit internal compiler errors
На мой взгляд, пример по ссылке как минимум странный. Зачем линковаться к константному массиву данных и дергать из него значения в рантайме, если можно вынести массив в заголовочный файл как constexpr, подключить его и тогда все операции с этим массивом перейдут в compile time, а в бинарник он вообще не попадет?

Не могут все операции с массивом перейти в compile time, за исключением тех случаев когда массив — промежуточный либо не нужен.


Возьмем простейший код:


constexpr int a[1000] = ...;
int k;
std::cin >> k;
std::cout << a[k];

Ну и как в такой ситуации компилятору a[k] вычислять-то?

… или будут, но в том месте, где потребуются. заполняясь побайтово? :-)

Вот бы все разработчики были такими дотошными и смотрели что делает их компилятор…

Многие это делают, когда наступает момент: "пора!" У меня всего 300кБ на код, так что rabin2 + сортировка символов по размеру и начинаем с самых больших, задавая им вопрос: а что у тебя можно улучшить?


Но мне приходится жертвовать, в основном, скоростью в угоду размера, что, в общем, не суть.


Но заниматься этим на каждом этапе разработки, это непростительная трата времени. Как показывает личный опыт, сумма времени потраченного на оптимизации "по ходу пьесы", обычно больше, чем монолитный кусок, "когда действительно нужно".

Я рассчитываю, что команда разработчиков VC++ исправит данный баг к выходу VS 2017 — в этом случае код можно было бы и не исправлять — но я не хочу ждать так долго. И я начал убирать модификаторы const в тех местах, где это вызывало подобные проблемы.

Звучит как огораживание костылями под отдельно взятый компилятор. Где-то читал, что для сборки хрома Google использует Clang — в нём поведение аналогично описанному в статье? Ну и после исправления бага в VS снова нужно будет проставлять const в соответствующих местах — имхо какой-то не системный подход.
Звучит, да. Для сборки Хрома используются разные компиляторы под разные платформы. Нет, после исправления бага в VS не нужно будет снова править код. Автор убирал лишь модификатор const у и так полностью константных объектов. На другие компиляторы (и пофигшенный VS) это не влияет.
UFO just landed and posted this here
Никак, в статье есть об этом — «Поскольку весь объект так или иначе является константным, удаление модификатора const у одного из его членов данных нисколько не уменьшает безопасность, а для компилятора VC++ по факту увеличивает её.».
Уменьшение потребления памяти на 200 КБ выглядит как выбрасывание кофеварки из самолета для уменьшения его веса.

Только разница в том, что кофеварка в самолете была нужна, а эти 200 КБ были лишними.

Не из самолёта, а из каждого ящика, перевозимого самолётом. Для Боинга с 5ю ящиками — незаметно, а из Цесны с сотней ящиков — очень даже.
Хром — тот ещё боинг, но и кофеварок в нём на целого пассажира наберётся.
и никто не скажет что наличие const должно бы определяться логикой программы, а не размером бинарника… компилятор поправят, а переделки const останутся
В программе должны быть и логика, и оптимизация (ну по крайней мере в программе уровня Хрома, которой пользуются миллионы людей). Компилятор поправят, переделки останутся — и не принесут никакого вреда, поскольку эти объекты и так константны.

А где нарушилась логика программы?

Ну, так если прочитать и понять(!) статью, то можно увидеть следующее: автор, использовав специальные средства, провёл работу над ошибками в плане проверки соответствия результата компиляции (даже так, уже круто!) логике программы. Нашёл кучу несоответствий именно логике программы и устранил. И — ура!!! Уменьшился размер, уменьшилось потребление памяти. И если второе "ура" было целью, первое оказалось приятным сюрпризом. Я не увидел в статье ни одного изменения, нарушающего логику. Ряд сущностей был переведён из переменных в константы (именно потому, что по логике это должно быть так), при этом ни одна константа не перестала быть константой, в том числе там, где const удалили (так как удалялись ИЗБЫТОЧНЫЕ const). И что конкретно Вам не понравилось, что автор сделал не так по-Вашему?
А переделки остануться именно в силу того, что они сделали объявления более соответствующими логике программы.

Избыточной константности не бывает. Это как константная пропертя, которая является тоже константной структурой. Кто-то может подумать "а зачем делать структуру константной, она же и так в константном поле" и уберет. Через пару месяцев нужно будет убрать константность свойства, и её уберут. А еще через пару месяцев кто-то запишет значение в массив, который предполагался быть readonly.


В случае добавления const — да, это исправление логики программы и синхронизация с ней исходных кодов. А вот убирание const — совершенно обратная операция, призванная выиграть 300кб памяти. Я вот даже не представляю, как константность может быть избыточной. Константность поля никак не зависит от константности типа поля, например. Это разные уровни просто — перезапись свойства, перезапись свойства свойства, перезапись свойства свойства свойства,… И каждая требует (или нет) const на своем уровне.

Баг в компиляторе или не баг, но константные поля в структурах вообще имеют мало смысла, потому что у структур обычно нет конструкторов, которые бы эти поля инициализировали. В коде хроме с этими const в структурах явно переборщили.

Запись нулей можно было бы пропустить. Данный массив — это глобальная переменная, которая инициализируется лишь раз при запуске программы, а в этот момент вся память гарантированно заполнена нулями, так что записывать нули поверх нулей — бессмысленная работа.


А почему память гарантированно заполненна нулями? Последний раз (было давно) в памяти был мусор оставшийся в наследство от бывшего владельца.

Если бы запущенный процесс в своих глобальных массивах мог бы читать чужой мусор — это было бы нарушением изоляции процессов и уязвимостью. Поэтому ОС при выделении памяти всегда ее очищает.

Sign up to leave a comment.