LINUX.ORG.RU

Ушат помоев в сторону крестолюбов

 , , ловите наркомана,


15

14

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

Последние 7 лет я пишу сугубо на C, и только под Linux (да, да -std=gnu99 и accept4, dup3, __attribute__((cleanup(dtor))) и прочие приятности, позволяющие сделать волосы шелковистее на 15.5%) и не понимаю, для чего вообще нужен C++? То, что на сишке делается красиво и элегантно, в крестах напоминает соитие парализованных дцпшников (к сожалению, утерял картинку, но именно этот образ всплывает в голове, когда вижу очередную порцию крестолапши).

Давайте посмотрим на типичного C++ разработчика: он использует STL, boost, многие любят Qt (не только для GUI), якобы чтобы «писать кроссплатформенный код». В итоге болезный не знает током ни WinAPI, ни POSIX — ничерта. Он абсолютно не разбирается, как работает целевая система, для которой пишет код! Крестокодер просто не осознает, какой лютый ужас кроется за его любимыми iostream-ами, какое лютое говно лежит в boost::filesystem::path, насколько убого-низкоуровневым является boost::asio в 2016 году.

Только крестораб может эпично обосраться и просадить производительность, забыв передавать по ссылке параметры для «горячих» функций (то есть, просто забыв написать «&» в нужном месте).

Также эти убогие завистливо смотрят на type inference в языках, проектировавшихся не как «C на стероидах», и в ответ начинают лепить template и auto не к месту, от чего код адово пухнет и даже IDE перестает его понимать.

Серьезно, просто прекратите писать на этом языке. В следующий раз, начиная новый проект, выберите java (щютка)/go/swift/rust/c. Прекратите насиловать труп и отравлять зловонием все вокруг!

Перемещено true_admin из talks

★★★★

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

И ты тоже ни черта не знаешь о том как uthash работает по большому счету.

Да говорю же тебе, знаю. Там меньше 1000 строк нормального понятного кода (включая комментарии и вспомогательные макросы для контроля целостности), что в два раза меньше, чем в /usr/include/c++/5/bits/hashtable.h

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

«C говно, потому в C++ я могу подключить ту же библиотеку». С тобой все в порядке? Бред какой-то несешь.

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

если будешь работать senior c++ developer, уверен что это будет последняя фраза перед твоим увольнением =)

Ты как-то очень хорошо думаешь о синьорах. Заказчика/нанимателя обычно интересует выполнение задачи.

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

А вот этот вот TOOLCHAIN_SPECIFIC_BUILD_DIR откуда возьмется. И содержимое в нем?

Кроме того, не понимаю в чем предмет спора. Вы опытный пользователь CMake, у вас с ним проблем нет. Так пользуйтесь на здоровье, раз вам нравится.

Я вам объяснил, что мне в CMake не нравится. Если вас это не убеждает, то не вопрос, для вас вообще ничего не изменится. Как и не изменится мое мнение про качество CMake как инструмента.

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

Из названия вообще непонятно что делает, безе перехода к объявлению/описанию вообще не ясно что там происходит.

Если handle_halign будет лямбдой перед свитчем, то все будет понятно. Если это будет отдельный метод, то у него может быть другое название, например, SetHorizontalAligmentParams().

eao197 ★★★★★
()
Ответ на: комментарий от stevejobs
#define warn_stat(call) \
	do { \
		if (stat != Ok) \
			warning("%s: %s failed (%d)", __FUNCTION__, call, \
					(int)stat); \
	} while (false)

Аааа, как же хочется уе*ать за такое. И это еще лайт версия. Я и похуже видал, но даже от этава ажж трисеттт!!111один

Кстати зачем тут do{}while(false)? тут даже break нет.

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

Я бы за одни #define без крайней необходимости руки бы отрывал.

Мальчишка был юн :-) Мальчишка так много читал про шаблоны в цепепе, что и правда поверил, что с их помощью можно обойтись без иных средств генерации кода :-)

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

Мальчишка был юн :-) Мальчишка так много читал про шаблоны в цепепе, что и правда поверил, что с их помощью можно обойтись без иных средств генерации кода :-)

В других языках как-то обходятся.

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

Главная проблема с этим макросом вовсе не в do{}while. А в том, что он заточен под наличие в локальном контексте переменной с именем stat и нужным типом.

А так сделать логирование с именем функции (+имя файла, +номер строки) в C++ без макросов не получится.

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

В других языках как-то обходятся.

В других проектах и без цепепе обходятся :-) Много таких проектов :-)

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

Ясен фиг, что главная проблема не в do{}while; Просто меня это тоже в ступор поставило.

А так сделать логирование с именем функции (+имя файла, +номер строки) в C++ без макросов не получится.

Это то понятно, но вот многострочные макросы я на дух не переношу. Да и define для констант тоже. Как я и сказал «без крайней необходимости».

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

Кстати зачем тут do{}while(false)? тут даже break нет.

Нда, вот это крестопрофессионализм

#define MACRO1(a, b) do_a(a); do_b(b)
#define MACRO2(a, b) { do_a(a); do_b(b); }
#define MACRO3(a, b) do { do_a(a); do_b(b); } while (0);
#define MACRO4(a, b) do { do_a(a); do_b(b); } while (0)

void do_a(int a);
void do_b(int b);

int main()
{
  if (true) MACRO1(a, b); else MACRO1(b, a);
  if (true) MACRO2(a, b); else MACRO2(b, a);
  if (true) MACRO3(a, b); else MACRO3(b, a);
  if (true) MACRO4(a, b); else MACRO4(b, a);
  return 0;
}
Попроси компилятор помочь.

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

Да говорю же тебе, знаю. Там меньше 1000 строк нормального понятного кода

И толку? Без знания теории это все тебе ничего не скажет. Эти хэш таблицы студенты в качестве курсовых вырыгивают по 2 раза в год.

Я не говорю, что Си говно. Я говорю что плюсы умеют все то же только больше и в плюсах сразу есть хороший, стандартный и относительно удобный набор инструментов. И они все в большинстве случаев работают хорошо. А там где нужно совершенство(в редких случаях), всегда можно подключить подходящую библиотеку.

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

А вот этот вот TOOLCHAIN_SPECIFIC_BUILD_DIR откуда возьмется. И содержимое в нем?

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

Кроме того, не понимаю в чем предмет спора.

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

Я вам объяснил, что мне в CMake не нравится. Если вас это не убеждает

Не то чтобы «не убеждает». С претензиями к синтаксису я согласен. Претензии к документации — вряд ли их возможно формально опровергнуть, но мне просто интересно, какие конкретно детали поведения, потребовавшиеся в твоей практике, там не описаны или плохо описаны, потому что мой список таких деталей состоит лишь из одного пункта. А претензию к отсутствию в CMake непосредственно сборщика я попросту не понял — что мешает рассматривать в качестве сборочной системы не cmake, а cmake && make?

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

Ты же понимаешь, что это извращения. Если ты do{}while(0); используешь так, то у меня к тебе нет вопросов.

#define MACRO1(a, b) { do_a(a); do_b(b); }
void do_a(int a);
void do_b(int b);

int main()
{
  int a,b;
  if (true) MACRO1(a, b) else MACRO1(b, a);
  return 0;
}

Имхо все остальное полный изврат. Хотя это тоже.

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

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

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

Без знания теории это все тебе ничего не скажет

Теория нужна на этапе построения хеш-функции. Дальше уже дело техники.

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

Хороший? На любителя. Стандартный? Наверное да. Удобный? Вот уж нет! Изобрази на iostream-ах

printf("%02.2f, %6s\n", 2.5, "text")

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

if (true) MACRO1(a, b) else MACRO1(b, a);

Неудивительно, что ты не любишь define. Такие люди рано или поздно делают

#define false 1
#define true 0

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

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

От любителя темплейтов и буста такое слышать даже смешно.

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

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

Ну вот и не нужно мне такое счастье.

А претензию к отсутствию в CMake непосредственно сборщика я попросту не понял — что мешает рассматривать в качестве сборочной системы не cmake, а cmake && make?

Бритва Оккама, наверное.

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

Теория нужна на этапе построения хеш-функции. Дальше уже дело техники.

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

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

printf

Хороший пример как по-тихому крэшнуть программу.

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

Изобрази на iostream-ах
printf(«%02.2f, %6s\n», 2.5, «text»)

fmtlib

fmt::print(std::cout, "{:02.2f}, {:<6}\n", 2.5, "text")
Поддерживает типы, для которых определен сдвиг в ostream. Бьет по рукам, если типы не совпадают.

А теперь вы что-нибудь простенькое на printf-ах повторите:

#include "fmt/ostream.h"

class Date {
  int year_, month_, day_;
public:
  Date(int year, int month, int day) : year_(year), month_(month), day_(day) {}

  friend std::ostream&operator<<(std::ostream&os, const Date &d) {
    return os << d.year_ << '-' << d.month_ << '-' << d.day_;
  }
};

fmt::print(std::cout, "The date is {}\n", Date(2012, 12, 9));

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

А теперь вы что-нибудь простенькое на printf-ах повторите

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

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

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

Да, как-то слишком просто :-) Для распечатки 3-х чисел явно не хватает класса трэитсов со SFINAE на борту :-)

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

Нда...

fmt::MemoryWriter writer

Я смотрю, стандарты-стандартами, но каждая библиотека пилит свой велосипед (конечно же, не совместимый с велосипедами других поставщиков) на тему строк и буферов. И концепцию итераторов особо не жалуют. Словом, классический крестовелосипед с квадратными колесами.

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

Я вообще макросы без крайней необходимости стараюсь не использовать, как я выше и сказал.

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

Печать произвольного типа.

Ложь №1: не любого, а лишь того, для которого определен ostream& operator<<(ostream &, const Type &obj).

В любой тип выходного потока.

Ложь №2: не в любой, а лишь в потомка ostream. Также есть перегруженная версия для FILE * (работать должно хреново, поскольку FILE* = void * — дальше догадайся сам).

Забавный факт №1: ни один крестоодепт даже не попытался изобразить тестовое задание через setw и прочее потоковое говно, вместо этого побежали искать какие-то либы, которых, к слову, нет в репозиториях бубунты. Крестоэкосистема как она есть.

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

и прочее потоковое говно

Кстати, да, от потоков шарахаются даже самые тёртые одепты :-) Видел слайды с какой-то конференции ++, где приводился подкапотный ужас i(o)stream :-)

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

Ложь №1: не любого, а лишь того, для которого определен ostream& operator<<(ostream &, const Type &obj

Так определи сам. В чем проблема?

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

Ложь №1: не любого, а лишь того, для которого определен ostream& operator<<(ostream &, const Type &obj).

В С++, если вы не знали, это де-факто и де-юре нормальное поведение.

Что вы в качестве такого предложите в С?

Ложь №2: не в любой, а лишь в потомка ostream.

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

Забавный факт №1

Тут от вас люди еще первого задания с хеш-таблицей не увидели.

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

Так определи сам. В чем проблема?

В таком случае, в чем проблема определит «оператор вывода в любой поток» как

void print_my_type(FILE *out, const my_type *v);
И использовать эту функцию в нужных местах? Перегрузка всего лишь синтаксический сахар.

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

Тут от вас люди еще первого задания с хеш-таблицей не увидели.

На второй странице посмотри.

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

написан на С++, и даже если их разработчиков попросили бы написать снова с нуля - они опять бы выбрали плюсы? Даже если новых разрабов набрать.

Крайне спорный вопрос. Сейчас бы 99% разрабов написало бы все на C# каком-нибудь. Запусти какой-нибудь квартус из директории с кирилицей - получишь сегфолт. Вот тебе и кресты. Причина там одна: легаси. Весь твой спецсофт писался во времена царя гороха, а иногда должен был работать даже не под юниксом каким, а аж под досом, как автокад.

А нового спецсофта нет, ибо тотальная монополия везде устоялась. Ну по качеству крестокод в каком-нибудь спецсофте тоже не блещет совсем.

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

Ну еще, правда, проблема с переносимостью: нет переносимого языка, на котором можно было бы лабать кривое нативное говно разом под все платформы, и чтоб не выжирало 64G памяти, как жаба, и чтоб с ООП, ибо функциональщина - не мейнстрим.

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

В таком случае, в чем проблема определит «оператор вывода в любой поток» как

Ох лол.

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

считается нетривиальным :-) Надо писать так
Видишь, было две строчки, а теперь просто = default !11 :-)

Ну толсто же.

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

Бритва Оккама, наверное.

скорее, синдром утёнка :)

anonymous
()
Ответ на: impl_ = nullptr; от anonymous

impl_ = nullptr;
детектор говнокода сгорел от зашкаливания

От чего же присваивание указателю nullptr в деструкторе считается говнокодом? :-) Давай, продемонстрируй тут свою некомпетентность :-)

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

Ну толсто же.

А разве не так принято сейчас определять деструкторы в современном цепепе? :-)

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

Открываем любой проект на С и читаем чейнжлог: исправили утечку, исправили segfault, исправили уязвимость, добавили минорную фичу, реализовав её в 100500 строк кода/лапши.

Правда. И все то же самое можно сказать про чейнжлог квартуса или кде.

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

потому что в нескольких соседних методах (не во всех, обычно, лол) написано

if (impl_)
wait. oh shi

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

потому что в нескольких соседних методах (не во всех, обычно, лол) написано
if (impl_)

Ахаха :-) Это где так пишут очередной стартап? :-)

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

практически везде, где встречается impl_ = nullptr;

зачем иначе присваивать значение, которое никогда не будет считано?

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

Вы утверждали что лисп для числодробилок лучше чем цпп.

Достаточно посмотреть ассемблерный листинг '+ в sbcl и заплакать кровавыми слезами. А так любой язык с обертками к BLAS/LAPACK, зачем себя насиловать и писать все руками?

Впрочем, видел людей, которые писали достаточно сложные вещи на си, городя руками чуть ли не комплексную арифметику, потому что так быстрее. Почему оно быстрее, я так и не понял, не вдавался.

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

практически везде, где встречается impl_ = nullptr;

зачем иначе присваивать значение, которое никогда не будет считано?

Так в чём говнокод тогда? :-) Присваиваем значение, потом проверяем :-) В старапах нынче что, в случае с unique_ptr<> проверки вида if (impl_) не делают? :-) unique_ptr<> за это не отвечает :-) Получается, говнокодите там у себя? :-)

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

Присваиваем значение

в деструкторе

потом проверяем

ну ок

на этом беседу с необучаемым можно заканчивать

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

Далеко не всякая числодробилка требует солверов СЛАУ.

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

Очень многие задачи числ. моделирования относятся к memory bound, поэтому на первое место выходит оптимизация хранения и обхода данных с учетом специфики задачи. Тут уже всякие извращения и велосипеды встречаются...

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