Готовлю к релизу небольшое обновление для RESTinio. Там суть в том, что в fmtlib есть возможность контроля за форматной строкой в compile-time. Для этого, когда мы находимся в рамках стандартов C++11/14/17, требуется помещать форматную строку внутрь макроса FMT_STRING:
fmt::print(FMT_STRING("The answer is {}\n"), 42);
Фокус в том, что макрос FMT_STRING должен применяться когда задан символ препроцессора FMT_ENFORCE_COMPILE_STRING. Если этот символ не задан, то форматная строка должна быть обычным строковым литералом.
Поскольку RESTinio -- это библиотека, которая может быть задействована в разных проектах с разными параметрами компиляции, то потребовалось модифицировать код RESTinio так, чтобы все было нормально и когда FMT_ENFORCE_COMPILE_STRING определен, и когда FMT_ENFORCE_COMPILE_STRING не определен.
Вроде как все сделал еще три недели назад, но приступить к подготовке релиза выдалась возможность только сейчас. Заодно оказалось, что fmtlib обновился до 9.1.0, поэтому я решил проверить RESTinio еще раз, уже с более свежей fmtlib.
И тут-то и оказалось, что в режиме C++20 и FMT_ENFORCE_COMPILE_STRING пара штатных тестов и один пример не компилируются clang-14.
Компилятор clang-14 как-то матерно ругался вот на такие строчки в одном из тестов (раз и два). Мол, какой-то из dependent type где-то в нутрях fmtlib не определен. А где и какой непонятно.
Пришлось несколько часов курить бамбук, пробовая и так, и сяк. Особенно удивляясь тому, что gcc-11 проглатывает этот же код нормально. Да и сам clang-14 похожий код в других местах вполне себе компилирует.
Лучик света забрежжил, когда я закомментировал вызов fmt::format на самом глубоком уровне вложенности (вот здесь).
Оказалось, что оставшийся вызов fmt::format после этого успешно скомпилировался, хотя до этого clang на него ругался.
Тут-то до меня дошло, что скорее всего имеет место какой-то глюк компилятора clang, который проявляется на слишком большом уровне вложенности лямбд.
Вынес часть функционала в отдельную вспомогательную функцию (делай раз, делай два) и...
Вуаля! Все скомпилировалось.
Морали не будет. Но будет озвучен вопрос, который меня серьезно озаботил: ну ладно, я-то давно люблюсь с C++ и C++ными компиляторами, падения с internal compiler error встречал неоднократно (к счастью, в последние годы все реже и реже)... А вот что было бы, если бы на моем месте был человек менее опытный? Который бы реально полез бы в потроха fmtlib чтобы разобраться что там за dependent type не определен... Вот сколько бы он времени на это убил бы?
Комментариев нет:
Отправить комментарий