LINUX.ORG.RU

Чистота кода

 ,


1

7

Вопрос к разработчикам на C++. На сколько толерантно вы относитесь к функциям из стандартной библиотеки C в коде на C++?

Например, к sscanf?

★★★★★

Не очень, если на это нет причин (например, производительность). Но порой причины как раз есть.

Pavval ★★★★★
()
Последнее исправление: Pavval (всего исправлений: 1)

sscanf

Резко отрицательно. Этим говном и на C не надо пользоваться. А так, форматеров аля printf в кресты так и не завезли :(

Stil ★★★★★
()

Именно sscanf? С большим подозрением.

tailgunner ★★★★★
()
Последнее исправление: tailgunner (всего исправлений: 1)
Ответ на: комментарий от DELIRIUM

http://fmtlib.net/

По теме - отношусь так же, как к использованию C функций в любом другом языке высокого уровня, т.е. отрицательно (с примерами, где это оправдано не сталкивался, но думаю, что в тех случаях это уже трудно назвать программированием на C++).

anonymous
()

C++ I/O стримы на дух не переношу, пользую везде C API (read/write/printf etc), точнее написал классы-обертки (без операторов << >>) пару лет назад и ими пользуюсь

Хотя коллеги активно их (стримы) используют (даже для форматирования строк)

zaz ★★★★
()

Судя по некоторым местным ораторам, меня надо убивать. Отношусь хорошо, так как сам им пользуюсь для быстрого парсинга (например, ip-адрес).

kachsheev ★★★
()
Последнее исправление: kachsheev (всего исправлений: 1)

Если как следует завернуть, чтобы не светило наружу - нормально, или даже единственный выход, если важна производительность (т.е. в большинстве случаев). Тем более - как ещё делать системные вызовы?

jcd ★★★★★
()
Ответ на: комментарий от anonymous

сторонние библиотеки там нельзя было использовать (ну либо копипастить оттуда код в свой исходник)

DELIRIUM ☆☆☆☆☆
()

Конкретно ублюдка scanf не должно быть и в C коде. А в общем - крайне отрицательно, потому что для всего есть более удобные и безопасные C++ конструкции.

anonymous
()

Нормально отношусь. Если есть удобная и такая же быстрая альтернатива на C++ - пользуюсь ею, иначе - остаюсь на функциях из C.

anonymous00 ★★
()
Ответ на: комментарий от DELIRIUM

не поверишь, сортировку вставками

там на сравнении строк можно сэкономить.
Массив слева от текущего элемента всегда упорядочен, можно выполнять поиск места для вставки бинарным поиском — это даст экономию только на сравнениях, но они-то для строк вполне дороги, будет на поиске logN вместо N.

bormant ★★★★★
()
Последнее исправление: bormant (всего исправлений: 1)

Например, к sscanf?

Ну, sscanf ещё ничего, а вообще - резко отрицательно. Если есть под рукой что-то C++ное, то лучше его - хоть буст, хоть Qt, хоть iostreams.

asaw ★★★★★
()
Ответ на: комментарий от DELIRIUM

Не знаю, откуда вы такие берётесь, но вас таких много и большинство мелких либ вполне рассчитано на использование через submodule или копипасту.

Usage
To use the fmt library, add format.h and format.cc from a release archive or the Git repository to your project.

anonymous
()
Ответ на: комментарий от anonymous

Там нужно было все исходники в одном файле (не считая инклюды стандартных хедеров).

DELIRIUM ☆☆☆☆☆
()
Ответ на: комментарий от bormant

Там не сравнение строк, там сортировка int32_t, но много io в файл.

DELIRIUM ☆☆☆☆☆
()

sscanf

Зло. Используйте безопасные обёртки.

RazrFalcon ★★★★★
()

В своём коде, скорее, отрицательно, ибо нефиг мешать два языка. В чужом - стараюсь относиться с пониманием, ибо обычно это не самая большая проблема, вычитываемая из чужого кода. :P

Ну и есть же божественный QtCore, при использовании которого не нужны ни этот ваш sscanf, ни в разы более громоздкие конструккции из STL.

anonymous
()

Если на использование нет особых причин, то стараюсь выпиливать и заменять на крестовые аналоги. Но крайне редко бывает, что и Си функции нужны.

zamazan4ik ★★
()

Вопрос задаёт телезритель из уфы

А это C или C++?

        template<typename ... Args>
        inline Exception(const char *format, Args ... args)
        {
            size_t size = std::snprintf(nullptr, 0, format, args ...) + 1;
            std::unique_ptr<char[]> buf(new char[size]);
            std::snprintf(buf.get(), size, format, args ...);
            m_what << std::string(buf.get(), buf.get() + size - 1);
        }

d_a ★★★★★
()

Именно в C++ коде плохо. Тот же sscanf меняю на istringstream.

Но если это просто С++ проект и там есть отдельные функции на C, то есть отдельные .c файлы с C кодом, то нормально.

fsb4000 ★★★★★
()
Ответ на: комментарий от drsm

Ну, в интернете написано что unique_ptr<T[]> правильно удалит, удалялкой для массивов.

d_a ★★★★★
()
Ответ на: комментарий от I-Love-Microsoft

До чего же «такой» C++ тошнотворен, и до чего приятен C++ в варианте Qt...

Qt-программист в треде.

tailgunner ★★★★★
()
Ответ на: комментарий от anonymous

А в целом мне кажется нормальный код

anonymous
()
Ответ на: комментарий от d_a

Попробуйте скомпилировать это C-компилятором и вариант C отпадет сам собой.

Одна из причин, почему код выглядит говном, в том, что создание временного std::string там наверняка лишнее.

eao197 ★★★★★
()
Ответ на: комментарий от d_a

Уехать в std::stringstream оно может и через write, а так лишняя аллокация на ровном месте. И проброс исключения становится еще дороже. Да и само хранение в Exception экземпляра std::stringstream вместо хотя бы std::string уже странно, т.к. конструирование пустого std::stringstream само по себе дорого.

Плюс, подозреваю, такого рода конструктор вполне себе проглотит нечто вроде:

throw Exception("id: %i, key: %s", index, std::string("Key"));
и не поперхнется во время компиляции. Зато во время исполнения это вылезет боком. Например, вот так.

eao197 ★★★★★
()
Ответ на: комментарий от eao197

Неть, почему, я проверял, ошибочку пишет и не компилирует:

            try { throw generic::Exception("%s", std::string("/path/to/file")); }
            catch (std::exception &e) { std::cout << e.what() << std::endl; }

exceptions.hpp:43:69: error: cannot pass objects of non-trivially-copyable type ‘class std::basic_string<char>’ through ‘...’
             size_t size = std::snprintf(nullptr, 0, format, args ...) + 1;
                                                                     ^
exceptions.hpp:45:60: error: cannot pass objects of non-trivially-copyable type ‘class std::basic_string<char>’ through ‘...’
             std::snprintf(buf.get(), size, format, args ...);
                                                            ^


А иначе нафиг он конечно нужен был бы :)

d_a ★★★★★
()
Последнее исправление: d_a (всего исправлений: 1)
Ответ на: комментарий от eao197

Конкретно это он не проглотит — т.к. std::string не скушается snprintfом.

Именно в этом и заключается моя главная претензия к printf/scanf и их товарищам в C++-коде: объекты туда не прокинуть, никакой перегрузкой для собственных типов поведения не добавить.

В одной проприетарной библиотеке, которой приходится пользоваться на работе, логгирование сделано как раз через ... и snprintf. Безумно бесит писать по пять раз в строке .c_str() и .ToString().c_str() при использовании их логгера. Лучше уж иостримы.

vzzo ★★★
()
Ответ на: комментарий от d_a

Я вам ссылку на wandbox дал, там вполне себе компилируется и ожидаемо не работает под gcc-6.3.0. Да и под VC++, полагаю, будет такое же поведение.

То, что clang ругнулся — это хорошо, но это всего лишь один из компиляторов.

eao197 ★★★★★
()
Ответ на: комментарий от anonymous

А какой смысл тогда оборачивать в string если в stringstream отдаешь?

Убрал уж :) Просто buf.get() остался.

d_a ★★★★★
()
Ответ на: комментарий от eao197

То, что clang ругнулся — это хорошо, но это всего лишь один из компиляторов.

А у меня и не clang, просто ГКК 4.8. Но вообще плохо конечно, непонятно зачем так "починили".

d_a ★★★★★
()
Последнее исправление: d_a (всего исправлений: 1)
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.