LINUX.ORG.RU

Производительность C++

 ,


7

13

Как насчёт производительности у C++ по сравнению с C? Мои предположения на текущий момент:

1) Код, не использующий возможности C++ (то есть по сути plain C), скомпилированный C++ компилятором будет иметь абсолютно ту же производительность, что и код на С.

2) Исключения и dynamic_cast медленные. Если нам важна производительность, лучше их не использовать.

3) Класс без виртуальных методов, должен быть по производительности эквивалентен сишной структуре и функциям, обрабатывающим её. Не считая копирования. Нужно везде, где можно использовать передачу по указателю или ссылке (собственно, если в Си делать memmove при передаче структуры в качестве аргумента, то это вызовет примерно такой же оверхед, как дефолтный конструктор копирования С++. Верно?).

4) Класс с виртуальными методами полностью аналогичен пункту 3, но при вызове виртуальных методов добавляется небольшой оверхед. Сишный эквивалент obj->vtable->func(obj, ...). Если сравнивать с plain C кодом, реализующим ООП в той же манере (каждая структура-объект имеет поле, указывающее на структуру, содержащую адреса функций работы с ней), то оверхеда по сравнению с plain C не должно быть.

5) При использовании атрибута класса final (если компилятор поддерживает соответствующий стандарт) даже при наличии виртуальных методов в нём, их вызов будет превращаться в прямые вызовы функций вместо обращения к vtable, если переменная имеет соответствующий тип, а не указатель/ссылка на его предка (который не final).

6) Шаблоны могут привести к разбуханию кода. Впрочем, #define-ы и inline-функции в C++ могут устроить то же самое. Вопрос: будет ли использование шаблона с одинаковыми параметрами создавать 2 копии реализации или же всё-таки компилятор догадается сделать её лишь один раз. А если шаблон используется с одинаковыми параметрами в нескольких объектных файлах? Будет ли реализация расшариваться между ними или у каждого своя?

7) Что насчёт inline-методов класса? (те, которые описываются прямо в момент определения самого класса, внутри блока class). Может ли их реализация расшариваться между модулями или в каждом будет своя копия (допустим, метод слишком длинный, чтобы инлайнится в момент вызова)?

Я не претендую на правоту, какие-то утверждения могут быть ложными. Хотел бы узнать, как обстоят дела на самом деле. А также какие подводные камни я ещё не знаю. Разумеется, речь идёт о последних версиях gcc/clang с включённой оптимизацией не ниже -O2.

★★★★★

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

Эта реализация демонстрирует то, что цепепе ты знаешь не очень хорошо, а ещё стиль не очень: Смотри:

// эти строчки не нужны, компилятор сгенерирует сам.
parsing_result(const parsing_result &) = default;
parsing_result(parsing_result &&) = default;

Специально для улыбчивых дебилоидов и им сочувствующим приоткрою немного суровую правду жизни: до сих пор в эксплуатации находятся C++компиляторы, которые не полностью поддерживают стандарт C++11. В частности, не генерируют move-constructor и move-operator по умолчанию. К таким компиляторам, например, относятся Visual C++ 11.0 и 12.0.

Если не указывать в описании класса двух процитированных выше строчек, то с такими «нестандартными» компиляторами нарываешься на использование копирование вместо перемещения. А вот если эти две строки указать, то возникает ошибка времени компиляции (на примере VC++12.0):

t1.cpp(8) : error C2610: 'parsing_result::parsing_result(parsing_result &&)' : is not a special member function which can be defaulted

Понятно, что дебилам, которые ничего не видят за пределами уютного мирка конкретного дистрибутива Linux-а это все не интересно. Но вот если занимаешься кроссплатформенной разработкой, то с такими вещами приходится считаться и подстраховываться.

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

Слив. Смайлик говорил, что он может сделать «правильнее», чем picojson. А picojson возвращает динамические строки.

О динамических строках имело бы смысл говорить, если бы parse() возвращала распарсенную строку. Но parse() в picojson возвращает сущность класса std::string, состояние которой является всего лишь индикатором успешного парсинга (пустая строка) или возникшей ошибки (сообщение об ошибке). Сущности Error от смайлика олицетворяют именно ошибки и содержат сообщения в виде строковых литералов. Слива нет.

Какие ваши доказательства?

Отсутствие типизации. Объект std::string может означать что угодно - это просто строка. А семантически, вот это

std::string parse(..);
// или
try {
  // ...
} catch (std::string& error) {
}
никак не может быть яснее, чем вот это
std::runtime_error parse(..);
// или
try {
  // ...
} catch (std::runtime_error& error) {
}

Напомню, что смайлик кричал про возврат runtime_error и таки привел в качестве решения проблемы вариант с runtime_error. Что говорит о признании им правомочными претензий к качеству реализации класса Error.

runtime_error он привёл потому, что это стандартный класс, как и string, а не его доморощенный Error.

Я не предоставлял своей реализации класса Error. Вы бредите.

А это что? http://www.linux.org.ru/forum/development/12649936?cid=12661944 (комментарий)

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

т.е. ты согласился что в микроядерных ОС мироядро не обязательно строго отделено от остальной части системы ?

Не соглашался. Микроядро отделено от остальной системы настолько, _насколько это возможно_. В Mach 1.x и 2.x драйверы отделить не смогли - они остались в ядре (в Mach 3.0 вроде и драйверы стали внешними). Но ФС, сеть, даже пейджеры - были внешними. А в NT всё это свалено в кучу - типичная монолитная ОС. Она может быть четко структурированной, но она всё равно монолитная (или, если угодно, модульная - загружаемые модули в наличии).

Более того - у NT нет и официального API микроядра, доступного извне (как Mach IPC). Официальный API - Win32. Типичная монолитная ОС. Впрочем, с уходом моды на микроядра ее и не называют микроядерной.

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

до сих пор в эксплуатации находятся C++компиляторы, которые не полностью поддерживают стандарт C++11

И ты, конечно, публиковал свой код на ЛОРе именно с учётом этого факта. Ну, ок.

Если не указывать в описании класса двух процитированных выше строчек, то с такими «нестандартными» компиляторами

Для демонстрации намерений лучше придерживаться стандарта. На то он и стандарт.

Понятно, что дебилам, которые ничего не видят за пределами уютного мирка конкретного дистрибутива Linux-а это все не интересно.

А причём тут дистр линуха, если gcc и clang есть везде. Ну, кроме тех мест, где есть только «нестрандартные компиляторы» :-)

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

О динамических строках имело бы смысл говорить, если бы parse() возвращала распарсенную строку.

Б**дь, что это за дебилизм на марше?!!! Да посмотрите вы в прототип функции parse из picojson наконец:

template <typename Iter> inline Iter parse(value& out, const Iter& first, const Iter& last, std::string* err)...
  
inline std::string parse(value& out, const std::string& s)...

inline std::string parse(value& out, std::istream& is)...
Все функции помещают результат разбора в out-параметр типа picojson::value. А возвращаемое значение либо указывает, что в out лежит корректное значение, либо содержит динамически созданное описание ошибки.

В этом плане использование std::string в качестве результирующего значения ничем не отличается от возврата int, long или какого-то другого типа.

Сущности Error от смайлика олицетворяют именно ошибки и содержат сообщения в виде строковых литералов.

Афигеть, дайте два. Вы тоже дебил или старательно стараетесь им казаться?

Объект std::string может означать что угодно - это просто строка.

Значение типа int (которое возвращается очень многими функциями стандартной библиотеки и стандарта POSIX) может означать что угодно — это просто знаковое целое. Тем не менее, спокойно используется для индикации ошибки.

А семантически

А семантически мы говорим о том, что picojson может использоваться в ситуациях, когда исключения просто-напросто запрещены. Поэтому апеляции к try-catch является лишь индикацией дебилизма говорящего. Ну или политкорректно: непонимания предмета.

А это что?

Ну и где там класс Error? Более того, где я предлагал использовать класс parsing_result? Речь шла о том, что у даже у такой тривиальной реализации parsing_result не было бы проблем смайликовского класса Error.

Или вы нашли еще какие-то фатальные проблемы у класса parsing_result?

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

И ты, конечно, публиковал свой код на ЛОРе именно с учётом этого факта. Ну, ок.

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

Как эти две строчки влияют на: а) производительность результирующего кода, b) на понятность кода и с) на сопровождаемость кода?

Иными словами: а не докопались ли вы до столба?

А причём тут дистр линуха, если gcc и clang есть везде.

ЧТД, за пределами уютненького мира конкретного дистрибутива линуха ничего видеть не хотим.

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

Б**дь, что это за дебилизм на марше?!!! Да посмотрите вы в прототип функции parse из picojson наконец:

Посмотрел...

В этом плане использование std::string в качестве результирующего значения ничем не отличается от возврата int, long или какого-то другого типа.

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

Значение типа int (которое возвращается очень многими функциями стандартной библиотеки и стандарта POSIX) может означать что угодно — это просто знаковое целое. Тем не менее, спокойно используется для индикации ошибки.

Тогда зачем parse() в picojson возвращает «динамически созданное описание ошибки», если фундаментальные типы аж в POSIX «спокойно используется для индикации ошибки»?

А семантически мы говорим о том, что picojson может использоваться в ситуациях, когда исключения просто-напросто запрещены.

Тогда «динамически созданное описание ошибки» - это излишество, лучше ограничиваться фундаментальными типами.

Ну и где там класс Error? Более того, где я предлагал использовать класс parsing_result? Речь шла о том, что у даже у такой тривиальной реализации parsing_result не было бы проблем смайликовского класса Error.

Ну это Error с другим именем и по-другому названными функциями-членами.

Или вы нашли еще какие-то фатальные проблемы у класса parsing_result?

Да, конечно. Самая фатальная проблема у класса parsing_result в том, что хотя класс громко и назван «parsing_result», там нет самого результата парсинга, а есть лишь сообщение об ошибке.

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

Иными словами: а не докопались ли вы до столба?

Ну ты же докопался до того, что в Error смайлика const char*, а не std::string в качестве члена. Почему бы и мне не докопаться до лишних строк в объявлении? :-) Я просто показал, что докопаться к мелочам можно ко всему и у всех. Но это смысла лишено. И не продуктивно. Работать нужно над фундаментальными проблемами, а не заморачиваться над мелочёвкой, которой в C++, увы, пруд пруди.

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

Ну ты же докопался до того, что в Error смайлика const char*, а не std::string в качестве члена.

Ваш Error ведет к утечками памяти.

Почему бы и мне не докопаться до лишних строк в объявлении? :-)

Повторю вопрос: к каким проблемам ведут эти две лишних строки?

Я просто показал, что докопаться к мелочам можно ко всему и у всех.

С каких пор утечки памяти стали мелочами?

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

Правильно, но зачем тогда нужен C++ с его возможностями типизации, если эти возможности в упор игнорировать, ограничиваясь лишь фундаментальными типами или типами стандартной библиотеки?
Тогда зачем parse() в picojson возвращает «динамически созданное описание ошибки», если фундаментальные типы аж в POSIX «спокойно используется для индикации ошибки»?

У меня полное ощущение, что приходится объяснять элементарные вещи малолетним дебилам. Но т.к. упрямства мне не занимать, то пожалуйта:

1. Решь шла не про то, нужен ли C++ или не нужен. Речь шла о том, чтобы сделать решение лучше, чем в picojson-ом. Где это решение?

2. По поводу «если эти возможности в упор игнорировать, ограничиваясь лишь фундаментальными типами или типами стандартной библиотеки?» претензии нужно предъявлять смайлику, который предложил возвращать runtime_error.

3. По поводу «зачем parse() в picojson возвращает «динамически созданное описание ошибки»,»: в результате парсинга JSON-а принято иметь в качестве результата либо успешно разобранный JSON-документ, либо индикацию неудачи разбора + описание причины неудачи. Описание причины неудачи естественным образом представляется в виде динамически созданной строки.

4. По поводу «Тогда «динамически созданное описание ошибки» - это излишество, лучше ограничиваться фундаментальными типами.»: да не вопрос, просто покажите как. А потом мы разберем насколько ваш вариант лучше варианта из picojson.

5. По поводу «Самая фатальная проблема у класса parsing_result в том, что хотя класс громко и назван «parsing_result», там нет самого результата парсинга, а есть лишь сообщение об ошибке.»: вы либо забыли про метод parsing_result::success(), либо под результатом парсинга понимаете что-то другое. Что именно?

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

Микроядро отделено от остальной системы настолько, _насколько это возможно_.

Фантазер епт

в NT всё это свалено в кучу - типичная монолитная ОС.

в NT типичное микроядро, а серверы в Executable не разделены как в классической микроядерной ОС и микроядро от этого не стало монолитным

Более того - у NT нет и официального API микроядра, доступного извне (как Mach IPC). Официальный API - Win32. Типичная монолитная ОС.

как видимый в юзерспейс API определяет архитектуру ? ты вообще какой-то далекий. Гипервизор например вообще не экспортируею никакой API в юзерспейс - он чего от этого монолитным стал ?

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

в NT типичное микроядро

Тут бы привести сравнение API «микроядра» NT с другими, но, конечно, ты его не приведешь. Ты просто знаешь, что у NT «типичное микроядро». Откуда знаешь? Да просто знаешь.

серверы в Executable

Интересно, а кто-нибудь, кроме тебя, называет, например IO manager «сервером», или ты один такой?

Гипервизор например вообще не экспортируею никакой API в юзерспейс - он чего от этого монолитным стал ?

Ты вообще какой-то далекий.

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

Ты просто знаешь, что у NT «типичное микроядро». Откуда знаешь? Да просто знаешь.

а ты просто знаешь что у MS не может быть микроядра - там же Win32 API - бугага

Интересно, а кт-нибудь, кроме тебя, называет, например IO manager «сервером»

не знаю, но это может быть отдельным сервером (сервисом) в классической микроядерной ОС а может и не быть. Но ты продолжай пыжиться, сраться и ссаться - может родишь более осмысленный аргумент - почему микроядро NT нельзя назвать микроядром.

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

а ты просто знаешь что у MS не может быть микроядра - там же Win32 API - бугага

Бгг. Ты, походу, запоминаешь только последнюю сказанную фразу. Ненадолго.

Я так понимаю, анализа API «типичного мироядра» не будет. Ну окей.

Но ты продолжай пыжиться, сраться и ссаться - может родишь более осмысленный аргумент

Да ты всё равно их не запоминаешь.

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

Это разница 1%, которая вызвана не инлайном, а разницой в сгенерированном коде.

ясно, вы даже банальный тест не можете нормально написать с первого раза

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

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

Конечно, комплексы нищеброда и жгучее желание самоутвердиться заставили его подзародчить тактики и байтики, но это все бессистемные обрывки знаний, не представляющие никакого интереса. Факт есть факт, что ни одну задачу, которую бы он сам себе придумывал или которую предлагали на ЛОРе, он так и не решил. И не решит никогда.

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

Ваш Error ведет к утечками памяти.
С каких пор утечки памяти стали мелочами?

Тот Error рассчитан на работу с литералами. Утечка будет, если в конструктор Error передать new char. Так что не передавай.

Повторю вопрос: к каким проблемам ведут эти две лишних строки?

Они ведут к соответствующей оценке кода. Раз автор их указал, значит автор не знает стандартные умолчания, что в свою очередь значит, что автор - не эксперт.

Да, кстати, твои success() и error_desc() (если правильно помню) можно и нужно объявлять noexcept, раз уж ты так щепетильно к накладным расходам относишься.

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

У меня полное ощущение, что приходится объяснять элементарные вещи малолетним дебилам. Но т.к. упрямства мне не занимать, то пожалуйта:

Просто тебе больше делать нечего, видимо.

1. Решь шла не про то, нужен ли C++ или не нужен. Речь шла о том, чтобы сделать решение лучше, чем в picojson-ом. Где это решение?

Опять ты не понял? Предложенное решение типобезопасное. Этим оно уже лучше и оправдывает использование C++ по назначению, опираясь на его сильную сторону - компиляцию.

2. По поводу «если эти возможности в упор игнорировать, ограничиваясь лишь фундаментальными типами или типами стандартной библиотеки?» претензии нужно предъявлять смайлику, который предложил возвращать runtime_error.

Вообще-то речь изначально шла об идиоматичном способе сообщений об ошибках в C++. Смайлик говорил, что для ошибок нужно использовать исключения. Ну и просто предложил вместо throw runtime_error, написать return runtime_error. И это выглядит логично.

Описание причины неудачи естественным образом представляется в виде динамически созданной строки.

Точно так же можно сказать, что «причины неудачи естественным образом представляются в виде строкового литерала, либо кода в виде целого числа».

4. По поводу «Тогда «динамически созданное описание ошибки» - это излишество, лучше ограничиваться фундаментальными типами.»: да не вопрос, просто покажите как. А потом мы разберем насколько ваш вариант лучше варианта из picojson.

Поменяй string на int в качестве возврата из parse(). Но это больше стиль C. В C++ принято уже давно исключения использовать.

5. По поводу «Самая фатальная проблема у класса parsing_result в том, что хотя класс громко и назван «parsing_result», там нет самого результата парсинга, а есть лишь сообщение об ошибке.»: вы либо забыли про метод parsing_result::success(), либо под результатом парсинга понимаете что-то другое. Что именно?

До тебя как-то туго доходит. Либо ты делаешь класс «описание ошибки», т.е. error_description, или error; либо ты делаешь класс «результат парсинга». Под результатом парсинга я понимаю объект JSON, с которым можно работать через функции и методы, т.е. твоими же словами: «в результате парсинга JSON-а принято иметь в качестве результата либо успешно разобранный JSON-документ».

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

Впрочем, с уходом моды на микроядра ее и не называют микроядерной.

Обчом вы спорите? NT вполне себе гибридная ОС, т.е. «ни то, ни се, а все вместе и еще че-то» :) В плане «моды на микроядра» про NT написано, что «Mach повлиял», но потом архитектор сменил дилера и влияние, наверное, закуклилось в экзеке ntoskernel.exe, куда все залинковано :)

«Windows NT's kernel mode code further distinguishes between the „kernel“, whose primary purpose is to implement processor and architecture dependent functions, and the „executive“. This was designed as a modified microkernel, as the Windows NT kernel was influenced by the Mach microkernel developed at Carnegie Mellon University,[20] but does not meet all of the criteria of a pure microkernel. Both the kernel and the executive are linked together into the single loaded module ntoskrnl.exe; from outside this module there is little distinction between the kernel and the executive. Routines from each are directly accessible, as for example from kernel-mode device drivers.»(с)

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

Конечно, ты просто выдрал фразу об отказе от использования исключений

Не ври, я отвечал на конкретное «язык должен использоваться либо полностью, либо никак».

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

И? Катлер увлекался микроядром — п-ц новость. Но потом «у нево открылся третий глаз» ему кормчие микрософта вилами подняли веки :)

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

Катлер увлекался микроядром — п-ц новость

Он тебе сам сказал? Катлер презирал Unix вообще и микроядра в частности.

Но потом «у нево открылся третий глаз»

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

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

Он тебе сам сказал? Катлер презирал Unix

VMS нежно любил потому что :) И как это связано с микроядрами — ненависть к юниксам? :)

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

Это твой источник в микрософте сказал? :) Вообще — «еще одна криптоконспирологическая теория» :)

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

Катлер презирал Unix

VMS нежно любил потому что :)

Нет. Он его сам по себе ненавидел: https://blog.codinghorror.com/showstopper/

Вообще — «еще одна криптоконспирологическая теория» :)

Ага, ага. В Википедии не написано - значит, конспирология.

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

Ну процитируй тут Катлера ниже, чо тебе жалко? :) «The last goal was crucial to Cutler. „Unix is like Cutler's lifelong foe,“ said one team member who'd worked with Cutler for nearly two decades.» (с) Хахахаха. «Один из тиммемберов сказал» (с) «executive usually responded to a Cutler complaint with the succint statement, „Fuck Dave.“» (с) А один из исполкома сказал «На х*й Дейва!» :) И ни пол-слова про микрокернел. От самого Дейва. Он затаился «в лоу профайле».

slackwarrior ★★★★★
()
Последнее исправление: slackwarrior (всего исправлений: 2)
Ответ на: комментарий от AnonCxx

Я бы сам на нём писал всегда, если бы он мог не только в экстерн из си, а и в инлайн си.

А расскажи подробнее. Правильно понимаю, что ты бы хотел в произвольных местах С++ разбавлять С? А чем конкретно С++ мешает? Тем что void* надо явно кастить? А чем ещё?

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

да знаю, просто иногда хочется высказать очевидность

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

Меж тем «Culter led development on a new microkernel-based operating system code-named Mica, which was to offer Unix-like and VMS-like „personalities“ on top of a common substrate of services.» (с) Плакал и возглавлял :) Итого: Катлер ушол-ушол из DEC потому что ненавидель микроядра... А в микрософте возглавил проект с микроядром — потому что любил жрать кактусы. Невроз какой-то да? :)

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

Тот Error рассчитан на работу с литералами. Утечка будет, если в конструктор Error передать new char. Так что не передавай.

Два вопроса:

1. Как Error защищает пользователя от ситуации, когда в конструктор Error по ошибке передается указатель на динамически созданную строку?

2. Если parse возвращает смайликовский Error с указателями на статические строковые литералы внутри, то как parse сможет вернуть описание возникшей ошибки парсинга? Например, что-то вроде: «в строке 10 не закрыта фигурная скобка, открытая в строке 9». Ведь picojson-овский парсер спокойно выдает такие описания.

Они ведут к соответствующей оценке кода. Раз автор их указал, значит автор не знает стандартные умолчания, что в свою очередь значит, что автор - не эксперт.

Автор не эксперт. Автор знает, что стандартные умолчания не работают в некоторых широкоиспользуемых C++ных компиляторах. Автору никто пока не показал, в чем именно состоит проблема с наличием двух этих строк.

Да, кстати, твои success() и error_desc() (если правильно помню) можно и нужно объявлять noexcept, раз уж ты так щепетильно к накладным расходам относишься.

Обоснуйте. В особенности для error_desc.

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

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

В чем заключается типобезопасность? Почему Error или runtime_error вы считаете более типобезопасными, чем std::string? Почему, по вашему мнению, использование std::string ведет к неоправданному применению C++?

Вообще-то речь изначально шла об идиоматичном способе сообщений об ошибках в C++. Смайлик говорил, что для ошибок нужно использовать исключения. Ну и просто предложил вместо throw runtime_error, написать return runtime_error. И это выглядит логично.

Перечитайте еще раз обсуждение. Идиоматический способ с исключениями не работает в ситуациях, когда исключения запрещены (и есть прикладные ниши, где исключения запрещены). В таких ситуациях идиоматично использовать возвращаемые значения. Использование return runtime_error вместо return string не логично, ибо, как уже показывалось ранее:

- работа с runtime_error в этом случае будет строится на точно таких же принципах, как и работа со string. Т.е. успех или неуспех определяется пустотой строки с описанием ошибки. Те же яйца, только с разных ракурсов;

- заворачивание текстового описания ошибки в runtime_error приводит к росту накладных расходов.

Т.е. принцип тот же, расходов больше. Так в чем логика?

Поменяй string на int в качестве возврата из parse().

Прекрасно. Как получить описание ошибки в случае ошибки парсинга?

В C++ принято уже давно исключения использовать.

Повторю в надцатый раз: есть ниши, где исключения не используются. В таких нишах picojson может применяться, а вот RapidJSON, в котором исключения бросаются, не может. Для таких ниш picojson отличный выбор. Для других ниш можно выбирать другие библиотеки.

Либо ты делаешь класс «описание ошибки», т.е. error_description, или error; либо ты делаешь класс «результат парсинга». Под результатом парсинга я понимаю объект JSON, с которым можно работать через функции и методы, т.е. твоими же словами: «в результате парсинга JSON-а принято иметь в качестве результата либо успешно разобранный JSON-документ».

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

Ну и еще раз: покажите уже вариант parse, который был бы лучше чем parse из picojson.

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

Меж тем «Culter led development on a new microkernel-based operating system code-named Mica, which was to offer Unix-like and VMS-like „personalities“ on top of a common substrate of services.» (с)

Как замечательно - уже просто «microkernel-based», без всякого «not pure microkernel». Вики цитирует маркетинговый отдел Microsoft.

А в микрософте возглавил проект с микроядром

На колу мочало, начинай сначала. Ссылка на то, почему он возглавил, приведена выше. Почему NT ни разу не микрооядерная - постинги еще выше.

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

Почему NT ни разу не микрооядерная - постинги еще выше.

где ?

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

Ссылка на то, почему он возглавил, приведена выше.

Ненене Девид Блейн :) Там нет прямой цитаты из Катлера :)

Вики цитирует маркетинговый отдел Microsoft.

Mica не имеет отношения к Майкрософт :)

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

Более того, в источнике который ты цитируешь: «The kernel was designed as a microkernel and components of the core were to run atop the kernel in a modular fashion; Cutler knew this principle from his work at Digital» (с) :))) Какой-то прям синдром навязчивого микро-ядра у мужыка, который «ненавидит микроядра» :) Это цитата из «Zachary, G. Pascal (2009). Showstopper!: The breakneck race to create Windows NT and the next generation at Microsoft. New York: E-Rights/E-Reads. ISBN 0-7592-8578-0.» p.57-66 :)))

П.С. Цитату разумеется подделал маркетинговый отдель Майкрософт, занеся редактору или Захару Г. Паскалю лично. :)

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

1. Как Error защищает пользователя от ситуации, когда в конструктор Error по ошибке передается указатель на динамически созданную строку?

Никак. Он не предназначен для работу с ними. Автор Error, который решил не работать с динамическими строками не станет добавлять лишние проверки. Пользователи Error осведомляются в документации, что «const char* - указатель на литерал, передача new char ведёт к утечке памяти».

2. Если parse возвращает смайликовский Error с указателями на статические строковые литералы внутри, то как parse сможет вернуть описание возникшей ошибки парсинга? Например, что-то вроде: «в строке 10 не закрыта фигурная скобка, открытая в строке 9». Ведь picojson-овский парсер спокойно выдает такие описания.

Это наглядно демонстрирует всю порочность подхода picojson. Ну и что делать с таким описанием какому-нибудь инструментальному средству или редактору, чтобы, например, подсветить ошибку в тексте? Парсить строку с описанием ошибки чтобы вычленить позиции? «Замечательно» просто. Т.е., ещё раз, string не предназначен для олицетворения ошибки. Он сгодится для описания части ошибки, но не для ошибки в целом. В целом же в каждом случае должен быть специальный объект для этого. И runtime_error и Error смайлика не подходит в данном случае для этого также.

Обоснуйте. В особенности для error_desc.

Что обосновывать, если данные методы в принципе не могут генерировать исключения? Значит нужно дать подсказку компилятору для оптимизации.

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

Ну и у тебя пруфа тоже нет, ЧТД, кроме домыслов :) И придирок к маркетинговому отделу — где-то в диапазоне от based до hybrid

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

Ну и у тебя пруфа тоже нет

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

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

В чем заключается типобезопасность? Почему Error или runtime_error вы считаете более типобезопасными, чем std::string?

В том, что любой функции, которая принимает string в качестве аргумента можно передать сущность более конкретной природы - «ошибка парсинга JSON». Под Error здесь надо понимать Json::Error. Компилятор соответствующим образом страхует от недоразумений.

Почему, по вашему мнению, использование std::string ведет к неоправданному применению C++?

Потому что в C++ очень просто создавать свои типы данных для типовой безопасности.

Перечитайте еще раз обсуждение. Идиоматический способ с исключениями не работает в ситуациях, когда исключения запрещены (и есть прикладные ниши, где исключения запрещены). В таких ситуациях идиоматично использовать возвращаемые значения. Использование return runtime_error вместо return string не логично, ибо, как уже показывалось ранее:

Прочитай мой довод насчёт парсинга строки ошибки для вычленения ошибки из строки. Теперь у меня есть стопроцентная уверенность, что просто string абсолютно непригоден как класс для ошибок.

Прекрасно. Как получить описание ошибки в случае ошибки парсинга?

Описание с конкретной позицией ошибки? Никак. Описание «произошла ошибка» - элементарно. Не мне тебя учить.

Повторю в надцатый раз: есть ниши, где исключения не используются. В таких нишах picojson может применяться, а вот RapidJSON, в котором исключения бросаются, не может. Для таких ниш picojson отличный выбор. Для других ниш можно выбирать другие библиотеки.

Ок.

Прекрасно. Покажите в коде на C++, как по вашему мнению это должно выглядеть, при условии, что библиотека должна уметь работать и в ситуациях, когда исключения запрещены.
Ну и еще раз: покажите уже вариант parse, который был бы лучше чем parse из picojson.

Некогда мне писать сюда ещё и код.

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

Ты так говоришь, будто не придирался к based и hybrid ссылаясь на «проплаченные маркетинговым отделом» домыслы Захарки... или тиммейтов Катлера, которые он собсна и цитировал:

«The structure of the kernel was itself complex, consisting of many pieces, which called each other or the hardware directly. Often pieces of the kernel called a bedrock layer of code, the „microkernel," which was the ultimate chief of staff within NT. Cutler, who had written a microkernel while at Digital, planned to write the one for NT. This seemed fitting to one teammate, who saw eerie parallels between Cutler's role on the team and the microkernel's authority over the operating system“ (с)

:) (А тиммейт просто Катлера с микроядром сравнил... Короче Катлер с командой изнасиловали Захарку и маркетинговый отдел микрософт. Так и запишем)

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

Ты так говоришь, будто не придирался к based и hybrid

Когда я начну _тебе_ что-то доказывать, ты меня одерни, окей? На случай, если я забуду, что ты внутри пустой.

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

Нафиг цитировать ОБС, если это не подкрепляет твои бугага по поводу цитат из википедии? :)

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

Он не предназначен для работу с ними. Автор Error, который решил не работать с динамическими строками не станет добавлять лишние проверки. Пользователи Error осведомляются в документации, что «const char* - указатель на литерал, передача new char ведёт к утечке памяти».

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

Попробуйте, ради хохмы, переделать вот этот простейший код под использование смайликовского Error:

std::string imit_parse( long & value, long limit )
{
	auto u = (value / 2) * 3 + (value % 5);
	if( u > limit )
	{
		const auto old = value;
		value = u - limit;
		return fmt::format( "value {} produces too large result: {}, limit: {}",
				old, u, limit );
	}
	else
	{
		value = u;
		return std::string();
	}
}
Просто попробуйте.

Это наглядно демонстрирует всю порочность подхода picojson.

Так я нигде и не говорил, что у picojson офигеть какой правильный подход. Всего лишь просил и прошу показать, как сделать лучше, оставаясь в рамках определенных условий.

И runtime_error и Error смайлика не подходит в данном случае для этого также.

О том и речь. Смайлик смеялся над возвратом string-а, но то, что он предложил, объективно еще хуже.

Что обосновывать, если данные методы в принципе не могут генерировать исключения?

Кто вам сказал?

Приведенный мной вариант parsing_result имеет одну фундаментальную проблему, на которую никто из критиков не обратил внимания, хотя она была на поверхности: ничто не мешает пользователю вызвать error_desc, даже если парсинг завершился нормально и описания ошибки нет. За такое использование error_desc нужно бить пользователя по рукам. В этом случае error_desc может иметь, например, такой вид:

const std::string & error_desc() const {
  if( success() )
#if HAVE_EXCEPTIONS
    throw std::runtime_error( "error_desc is not available for successful result" );
#else
    std::abort();
#endif
  return desc_;
}

Значит нужно дать подсказку компилятору для оптимизации.

У компилятора и так достаточно информации для оптимизации. noexcept используются для несколько других вещей.

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

В том, что любой функции, которая принимает string в качестве аргумента можно передать сущность более конкретной природы - «ошибка парсинга JSON». Под Error здесь надо понимать Json::Error. Компилятор соответствующим образом страхует от недоразумений.

Эту сущность, как я понимаю, вы сами придумали. Вам хочется, чтобы picojson возвращал некую структуру с детализированным описанием ошибки. Авторам picojson этого не хотелось. Пользователям picojson, как я понимаю, это так же не нужно. Их вполне устраивает возврат string-а.

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

Но виноват, конечно, C++.

Некогда мне писать сюда ещё и код.

А как дышал, как дышал. Звиздеть каждый может. А как код показать, так фейлы вроде смайликовых.

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

Попробуйте, ради хохмы, переделать вот этот простейший код под использование смайликовского Error:

Мне не надо пробовать, я прекрасно понимаю, что литералы имеют статическую природу. Error смайлика для ошибок вида «неправильно составленная строка JSON» или «в строке JSON присутстуют недопустимые символы».

Всего лишь просил и прошу показать, как сделать лучше, оставаясь в рамках определенных условий.

Лучше - это структурированный error. Если исключения прям уж нельзя, то ещё лучше - это parse_result с error и json_obj на борту. И всё это можно сделать без потерь производительности. Код показывать не буду.

О том и речь. Смайлик смеялся над возвратом string-а, но то, что он предложил, объективно еще хуже.

Лучше с т.з. типовой безопасности.

Приведенный мной вариант parsing_result имеет одну фундаментальную проблему, на которую никто из критиков не обратил внимания, хотя она была на поверхности: ничто не мешает пользователю вызвать error_desc, даже если парсинг завершился нормально и описания ошибки нет.

Ничего аномального конкретно здесь не вижу. Предложенная лапша с макросами - это костыль. Фундаментальная проблема - это отказ от исключений.

У компилятора и так достаточно информации для оптимизации. noexcept используются для несколько других вещей.

Ну озвучь уже наконец для каких это «других вещей».

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

Эту сущность, как я понимаю, вы сами придумали. Вам хочется, чтобы picojson возвращал некую структуру с детализированным описанием ошибки.

Именно структурированный Error.

Авторам picojson этого не хотелось. Пользователям picojson, как я понимаю, это так же не нужно. Их вполне устраивает возврат string-а.

Меня не устраивает, поэтому picojson использовать не буду.

И тут приходят анонимные аналитики, и говорят, что данный подход говно и они бы сделали лучше.

На их взгляд.

На просьбу показать, как бы это выглядело, выкатывается откровенный говнокод.

На твой взгляд.

Но виноват, конечно, C++.

Так и есть :-)

Звиздеть каждый может. А как код показать, так фейлы вроде смайликовых.

К тебе это тоже относится, судя по числу комментариев.

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.