Vitaliy Aksyonov написал(а) к Nil A в Feb 23 14:38:16 по местному времени:
Привет, Nil!
06 Feb 23 22:07, ты писал(а) мне:
VA>> Есть желание заняться выпиливанием malloc/free и заменой на new,
NA> Заодно и все memset() и memcpy() выпилить, а наче овчинка выделки не
NA> стоит.
Согласен. Причем можно начать "есть мамонта" кусками. Чтобы не делать огромные изменения сразу. Их сложно будет проверять.
NA> Заодно и все рукописные динамические массивы, линкед-листы, и все те
NA> дата-стракчерсы, что надо самому писать на plain C, то в C++ можно
NA> немного контейнеры готовые применить, уже ~ 20% всего кода просто
NA> выпилиться.
И их туда же. :)
NA> Заодно все char* на какие-нибудь std::string, но лучше на ICU, или
NA> ложить в string только UTF.
Я тоже думал о замене фиксированных буферов на строки. По крайней мере там, где они уместны. Насчет UTF - это слишком много сразу. Не прожую. Может потом. Если желание не пропадет.
VA>> чтобы побочные эффекты конструкторов не терялись.
NA> В эпоху Си-с-классами, когда не было таких слов, как RVO, не говоря
NA> уже об "современном" C++11 с rvalue и мув-семантикой, то вот писали
NA> как просто структуры, которые можно memset и memcpy, и пофиг что там
NA> вообще виртуальная функции есть, т.е. vtable, и что такие типы ниразу
NA> не POD, чтобы их побитово туда-сюда.
NA> Но это уже большой рефакторинг получается.
Да нет. Убрать memset там, где должен быть конструктор - не такая уж огромная задача. Мало того, можно сделать feature branch, порезать задачи и навалиться толпой, если есть еще сумасшедшие. ;)
NA> А главное, ну окей, проверишь ты ручками на Jam/Squish/Opus базах, а
NA> там в голдеде только разных баз и форматов с десяток, где ты такие
NA> референсные найдёшь, или ты зачекинешь, а вы, братцы, сами там
NA> проверяйте, если что поломается, то может починю, а может и забью, так
NA> как мишен мой закончился на этом.
1. Можно сделать юниттесты. Для рефакторинга это самый правильный способ.
2. Без помощи, конечно, будет сложно и затянется на долго.
VA>> Плюс убрать странные конструкции в виде:
VA>> recptr = new char [recsize];
VA>> throw_new(recptr);
NA> В эпоху Си-с-классами.. говорил вроде уже, не было стандарта на то,
NA> что new возвращает (void*)0 или кидает исключение. Собственно,
NA> исключения только потом придумали. А потом ещё и темплейты придумали.
NA> Сегодня это смешно, но так было.
Я понимаю, что древние компиляторы вполне могли работать так. Тут вообще сомнительный код. Если память уже кончилась, то вызывать какой-то еще код, который попытается записать лог (и потенциально тоже будет выделять память) - затея не очень здравая.
NA> Сегодня new будет кидать исключение, и надо его ещё заставить
NA> возвращать nullptr путём new(std::nothrow)
NA>
https://en.cppreference.com/w/cpp/memory/new/nothrow
NA> А кто более прошаренный, так и вовсе скажет, что на x86_64 у тебя new
NA> всегда вернётся без ошибки, просто памяти виртуально дехера, но потом
NA> ты словишь плохой автобус (SIGBUS).
Не всегда. Если тебе нужен большой кусок - то виртуальная память тут не поможет. Упадет именно аллокатор.
NA> А кто ещё ещё более прошаренный, тот скажет, ну кагбэ что вообще можно
NA> сделать, когда кончается память, данихера полезного не сделаешь,
NA> позакрывать все файлы, и в аборт. Кстати, ещё вопрос, тебя снесёт
NA> SIGBUS, или таки oom killer ;-) А нет, мы же проверяем возврат
NA> malloc() и new, и делаем что-то разумное при этом.
99%, что прибъёт OOM Killer. Только это может быть не линукс, а какая-то венда. А там OOM Killer нетути. ;)
VA>> Это ведь имеет смысл только в случае, если код собирается без
VA>> поддержки исключений.
NA> Ну я вот щас собиру без поддержки исключений. Есть два варианта,
NA> компилятор тупо вставит std::terminate() в том месте. Второй вариант,
NA> современный компилятор, увидит -fno-exceptions и throw в коде и
NA> откажется компилировать.
Расскажешь о результатах. Интересно.
VA>> Кто-то знает, есть ли такие сборки или это тоже
VA>> лучше выкосить?
NA> Думаю gcc 4.8 примерно должен собирать, и ещё из реальных мамонтов -
NA> Open Watcom 2.0.
Напишу в GOLDED попозже. Поспрашиваю, что там используют. 4.8 - вполне может использоваться в CentOS 7 именно он. Самый простой способ - не использовать C++11, а пилить в C++03 или даже 98. Но даже там есть нормальный STL.
Best regards,
Vitaliy Aksyonov.
... Чем дальше в лес, тем "ну их, дрова".
--- GoldED+/LNX 1.1.5-b20220504