Как стать автором
Обновить

Комментарии 36

Ок, аргумент в пользу Haskell принят.
НЛО прилетело и опубликовало эту надпись здесь
Я к тому, что type matching на этапе компиляции в Хаскелле сильно естественнее выглядит.
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
Я бы с удовольствием, а куда нужно обратиться? Может кто-то уже знает как?
НЛО прилетело и опубликовало эту надпись здесь
А почему нельзя сделать подобный код:

template< class T >
constexpr inline auto GET_Nth_CHAR_SPEC(N, const T (&LIT)[] ) -> decltype(T)
{ return N < sizeof_literal(LIT) ? LIT[N] : '\0'; }

Я правда не уверен, что все правильно написал, но смысл в том, чтобы вместо макроса шаблонную функцию сделать.
Конечно можно, это даже лучше будет, поскольку литерал не будет копироваться еще раз.
Ладно, а почему вы так тогда не сделали? Вариант — для облегчения читабельности кода не прокатит, этому коду уже ничем не поможешь :)
Просто интересно, в контексте бурных холиваров о вреде макросов.
Что-то на волне с макросами забыл о существовании функций))) Может по-этому они зло
Странно, я как посмотрел на этот фрагмент кода:

template< class T, std::size_t N >
constexpr inline std::size_t sizeof_literal( const T (&)[N] )
{ return N; }

// макросы для взятия N-ого элемента литерала
#define GET_Nth_CHAR_SPEC(N, LIT) (N < sizeof_literal(LIT) ? LIT[N] : '\0')

Так у меня возник некий дискомфорт, в связи с неединообразностью стиля очень похожих вещей.
Но вообще бывает, я сам помню generic контейнеры на пуре си на макросах писал, знаю, как оно увлекает :)
Отвратительное решение проблемы. Всё делается гораздо проще, берётся исходники printf из CRT и уже прямо в ней (на чистом C) добавляются небольшие проверки валидности аргументов, на всё уйдёт пару часов с тестированием (моё время). Причём можно сразу решить, что делать, например, если кл-во аргументов не соответствует кол-ву спецификаторов: ошибку возвращать, игнорировать, пропускать неподходящие/лишние и т.п.
я примерно понял о чем речь, но по-моему вы имеете ввиду рантайм
А вы уверены, что лицензия вам позволяет «берётся исходники printf из CRT»?
Неговоря уже о том, что в статье речь идет о времени компиляции.
Да, лицензия GPL позволяет это делать.

Да, в статье идёт речь немного о другом, но вариант с правкой библиотечной printf гораздо эффективнее и универсальнее. Представь, что форматирующая строка не может быть заранее задана, до компиляции программы, а может меняться значительно позже релиза, например, это часть пользовательской локализации интерфейса.
Сначала про эффективнее. Разработка? Исполнение-то явно замедлится.

Потом про «форматирующая строка не может быть заранее задана».
Если кратко, то так делать нельзя.
Если не сильно кратко, то во-первых пример плохой, т.к. при локализации часто требуется переставлять аргументы местами, чего с printf сделать не получится. Тогда уж boost::format.
Во-вторых, это же классическая атака на программы на Си. Как только у вас появляется printf(format, args), вы можете сделать дамп памяти, подсунув в format (пользовательскую локализацию, ок) длинную строку с одними только "%s".
Не очень понял комментарий, это вопрос или нет, мне или нет? :-\

Но, в общем случае, если уж решили модить printf, то естественно "%s" делается безопасным. Собственно, если касается дело локализации, то изменяемый снаружи только «format», а «args» скомпилирован жёстко.
Про эффективнее — вопрос, остальное — возражение.
О том и речь, что скомпилированные args — это не гибко, а задавать формат опасно в принципе при использовании printf. Что касается, «сделаем printf безопасным и потом будем локализовывать именно так», то это странно, т.к. есть более правильные способы.
Ну и модят printf на этапе компиляции, иначе он будет медленно работать.
Компилятор gcc умеет статически проверять соответствие форматной строки и аргументов в printf.
Не только gcc, есть еще много утилит для статического анализа кода, но это совсем не то, это другой уровень абстракции: код проверяют снаружи, этот же подход разрешает делать это изнутри.
Не знаком с этим новым значением слова «абстракция» :)
Подход как подход кстати — свои достоинства есть что у статического анализа что у подобных проверок во время компиляции.
Но честно говоря к специализированным инструментам у меня доверия больше.
Больше, чем к коду, написанному по стандарту языка, и который в общем-то, вы можете изучить сами и даже модифицировать?
Подозреваю, что изучить или даже модифицировать мне будет проще как раз исходники gcc или clang.
Как же вы живёте-то? Вам за что зарплату платят?
Я никогда не в восторге от кода, который выглядит сложным более чем для 50% программистов.
И реализация, и использование — усложнено.
Больше сложности — больше места для ошибки.

Но как разминку для ума — одобряю :-)
Для меня этот код не сложен, поэтому ошибок там нет=)
С использованием согласен: вариант с шаблонизацией литерала в случае неправильного использования из-за препроцессинга дает далеко-не-сразу-понятные ошибки.
Ну а все остальное, а особенно кортежи, по моему проще пареной репы.
Вы не с той стороны смотрите на проблему. Написать код — это 10% работы.
Остальные 90% — поддерживать его на протяжении следующих 20 лет, когда вам лично уже будет не до него.
Ну вы знаете, в большей части boost'а чёрт ногу сломит, однако же его можно и нужно использовать.
Верно. Но у буста есть саппорт какой-никакой, и он обеспечивает поддержку этого безумства в долгосрочной перспективе :-)
Поддержка безумства О_о
5+
НЛО прилетело и опубликовало эту надпись здесь
С потоками согласен, я вообще ненавижу С++ не использую printf.
А действительно дополнительное заворачивание в TEMPLATE_LITERAL выглядит громоздко?
НЛО прилетело и опубликовало эту надпись здесь
Даже в текущем виде constexpr — головная боль для создателей компилятора. По словам разработчиков Clang это самая сложная для реализации часть C++11, и просили ни в коем случае не расширять эту функциональность.
Ну как же нельзя, я же уже писал об этом. Создаем pack длинны кортежа, а далее подставляем в функцию взятия элемента:
template<int... INDXs>
T apply(FuncType f, tuple t)
{
    return f(get<INDXs>(t)...);
}

Примерно так.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории