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)

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

Цена контроля. Если такая зверская власть не нужна, берем кресты язык с GC. Не упарываться же борщемрастом в самом деле?

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

В QtCreatore отличная навигация же. Слева внизу поле вводе - вводи все что нравится и очень быстро находишь нужное место. Ну и ctrl+click очень радуют. Только на auto часто затыкается (в нашем большом проекте)

Это всё есть в KDevelop, только лучше.

И почему же оно в KDevelop лучше, если он основан на том же Clang?

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

Смолток для демонстрации как все это выглядит на нормальном языке.

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

да. но это скорее для того, чтобы сократить количество вариаций stl до одной единственной реализации

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

Если (или когда) он будет кросплатформенным (IBM Power, MIPS, ARM), тогда Rust будет достаточно интересным языком.

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

Если (или когда) он будет кросплатформенным (IBM Power, MIPS, ARM), тогда Rust будет достаточно интересным языком.

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

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

Wut? Когда успели?

Давно.

Они ж в нестабильных были и неподдерживамых официально?

Хм. А что ты называешь «нестабильными»? Не припоминаю, чтобы этот термин использовался в отношении поддержки платформ. Есть tier-ы, упомянутые тобой платформы - tier 2: https://doc.rust-lang.org/book/getting-started.html

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

Так они гарантируют сборку, но не работу на Tier2 же.

Работу они вообще нигде не гарантируют. Но я так понимаю, что твое пожелание сводится к «поддержка ARM, Power и MIPS должна быть на уровне x86»?

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

вы читать разучились, какая вкусовщина?

template<typename T, typename T2, BOOL WINAPI deleter(T2)> class GDIObj {
	T obj = nullptr;

	inline GDIObj &Replace(T obj_)
	{
		if (obj) deleter(obj);
		obj = obj_;
		return *this;
	}

public:
	inline GDIObj() {}
	inline GDIObj(T obj_) : obj(obj_) {}
	inline ~GDIObj() {deleter(obj);}

	inline T operator=(T obj_) {Replace(obj_); return obj;}

	inline operator T() const {return obj;}

	inline bool operator==(T obj_) const {return obj == obj_;}
	inline bool operator!=(T obj_) const {return obj != obj_;}
};

Зачем тут эта тьма инлайнов? По сути, ключевое слово inline выродилось по смыслу в «этот метод нарушает ODR». Непосредственно на инлайнинг оно не влияет, компилятор все такие конструкции игнорит и расставляет как ему больше хочется. Разве что там __attribute__((always_inline)).

Функция Replace написана отвратительно. Если написать x = x, всё сломается.

Вообще страшный класс.
Первое, непонятно зачем этот велосипед вместо std::unique_ptr?
Второе, не очень приятно что T должен быть обязательно указателем. Из-за этого читаемость кода резко падает.

Код написан человеком знакомым с синтаксисом языка, но не с тем, что стоит за ним. Это примерно как свежие пришельцы из C++ в Java создают thread, который раз в секунду вызывает System.gc()

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

Вот вам реально нужны эти архитектуры или вы просто нашли к чему прикопатся? Про ARM еще ок, но остальное вообще полуживое.

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

Про ARM еще ок, но остальное вообще полуживое.

Power вполне жив. И да, есть люди, которым нужны эти архитектуры. Мне вот еще хочется Microblaze.

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

Я сейчас изучаю ассемблер под zOS. Так что стюардесса ещё шевелится, хоть её и откопали.

Присоединяйся. И да, 6% - это даже больше, чем онтопик на десктопе.

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

Лол. Чё вы меня спрашиваете? Я не автор кода.

inline видимо с давних времён, когда он еще что-то значил.

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

Вас послушать, так любой код на java - это вершина совершенства.

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

Шок, rust пишут не для вас, а для большинства. И x86 - большинство. Не переживайте: всё будет. Языку полтора года только.

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

Забыл - функции, тело которых написано внутри класса, уже являются авто инлайновыми :) В данном случае слово inline не было нужно даже в те времена, когда что-то значило по основному предназначению :)

Лол. Чё вы меня спрашиваете? Я не автор кода.

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

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

Я не скажу за популярные компиляторы, но inline используют до сих пор. Взять тот же Qt. Видимо есть достаточно тупые компиляторы.

И даже в gcc/clang добавление inline иногда влияет на поведение.

Ну и как я уже сказал: код не настолько ужасен, как вам кажется.

Забыл - функции, тело которых написано внутри класса, уже являются авто инлайновыми

Такие базовые вещи я не забываю.

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

Зачем тут эта тьма инлайнов? По сути, ключевое слово inline выродилось по смыслу в «этот метод нарушает ODR». Непосредственно на инлайнинг оно не влияет, компилятор все такие конструкции игнорит и расставляет как ему больше хочется. Разве что там __attribute__((always_inline)).

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

Функция Replace написана отвратительно. Если написать x = x, всё сломается.

Проблема не в Replace. И сломается оно даже если написать x = y. И если вот так: GDIObj x(y). Реальная проблема в том, что автор класса не закрыл явно оператор копирования и конструктор копирования для GDIObj.

Первое, непонятно зачем этот велосипед вместо std::unique_ptr?

Потому, что автор хотел явно разделить два типа WinAPI-шных хендлов.

using HDCObj = GDIObj<HDC, HDC, DeleteDC>;
using HFONTObj = GDIObj<HFONT, HGDIOBJ, DeleteObject>;
using HBITMAPObj = GDIObj<HBITMAP, HGDIOBJ, DeleteObject>;
Вероятно для того, чтобы компилятор нормально съедал тип deleter-а.

Кроме того, непонятно, когда именно этот класс был написан. Может еще во времена, когда адекватной поддержки C++11 в VC++ еще не было. А потом его лишь слегка подрихтовали.

Второе, не очень приятно что T должен быть обязательно указателем. Из-за этого читаемость кода резко падает.

Класс рассчитан на работу в WinAPI-шными HOBJECT-ами. Что там скрывается под HOBJECT-ом — деталь реализации.

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

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

eao197 ★★★★★
()

Пришлите, пожалуйста, ссылки на проекты, написанные на идиоматическом C++11/14 без использования устаревших конструкций.

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

Шок, rust пишут не для вас, а для большинства

Так раст системный или нет? Большинству он не уперся, а вот платформ-меньшинства как раз должен бы удовлетворять.

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

Первое, непонятно зачем этот велосипед вместо std::unique_ptr?

Судя по тому, что ты лепечешь, тебе определённо стоит взглянуть на потроха этого «не велосипеда» под названием std::unique_ptr в том же GCC и дать свою экспертную оценку :-) Интересно, что для тебя лучше, написать class Impl; Impl* impl_; или подключить <memory>, разворачивающийся в 600 кб текста в заголовок лишь только чтобы написать «идиоматичный» и «современный» код на цепепе - std::unique_ptr<Impl> impl_, при этом всё также определяя деструктор и специальные операторы врукопашную, только теперь с помощью = default :-) Лол :-)

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

написать «идиоматичный» и «современный» код на цепепе - std::unique_ptr<Impl> impl_

Извини, я больше не могу терпеть. Буэээээ....

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

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

Впрочем, с движком в QtCreator тоже не особо хорошо. Уж не знаю, что там накосячено, но я помню, что он ломался на каком-то коде, на котором KDev не ломался.

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

подключить <memory>, разворачивающийся в 600 кб текста

Пока всё это добро собирается за приемлемое время — какая разница, во сколько текста он там разворачивается, я же не собираюсь препроцессированные листинги читать.

при этом всё также определяя деструктор и специальные операторы врукопашную, только теперь с помощью = default

То ли дело писать весь бойлерплейт самому!

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

То ли дело писать весь бойлерплейт самому!

Его по-любому нужно писать этот бойлерплейт в единице трансляции, что в случае с голым указателем в качестве члена класса, что в случае с unique_ptr<T>, т.к. T будет неполным, т.е. opaque :-) Просто в первом случае бойлерплейт чуть-чуть длиннее :-) И когда тебе нужно это сделать для сотни классов, то без разницы, напишешь ли ты в сотне мест = default или напишешь delete impl_; impl_ = nullptr; :-)

Какой более сильный аргумент за использование unique_ptr в пимпле ты ещё можешь привести? :-)

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

А при чём тут шланг (движок разбора исходников),

Вот при этом:

invy> В QtCreatore отличная навигация же. Слева внизу поле вводе - вводи все что нравится и очень быстро находишь нужное место.

intelfx>Это всё есть в KDevelop, только лучше.

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

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

ты как бы хочешь намякнуть, что в мире С++ говнарей не увольняют?

Шеренга индусов (с оплатой построчно) приветствует тебя, Цезарь! ))

если так, начинаю догадываться, в чем проблема С++...

у каждой настоящей цыганки дар гадания передается из поколения в поколения, но квантовую гравитацию цыгане пока еще не открыли...

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

всего [..] не осилил, слишком много
плюсики
overэнженеринг
сишечка
бяка
ужасс
мне сложно понять

«хипсторы» в треде, все въ лимузинъ!

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

Я конечно даже до джуниора по крестам не тяну, но уже понимаю что написан какой-то ад. Если бы такое было написано на Java, я бы прописал автору промышленную дозу галоперидола.

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

А то получится как в известной копипасте...

Итак, канадский программист сделает то, чего китайцы не рисковали делать в течении трех долгих лет. Он, при помощи дебагера, отследит место, где статическая переменная приняла значение -1 вместо правильного 0, и решительным движением заведет рядом вторую переменную с правильным значением. Баг погибнет в неравной схватке с канадским программистом.

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

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

Но в крестах так всё.

юношеский максимализм - вот твое все

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

Рекомендую начать с чтения книги по паттернам проектирования GOF (чтобы понимать как писать код с использованием этих паттернов и не плодить захардкоженые свичи копипастой).

неофиты - самые истые отстаиватели религиозных ценностей своего культа, во все времена

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

Использую то, что там «искаропки».

В моем случае не подойдет, потому что:

On the downside, for large projects using Clang as code model is slower than using the built-in code model. Clang does not need to generate object files, but it still needs to parse and analyze the source files. For small projects that only use STL, this is relatively fast. But for larger projects that include several files, processing a single file and all the included files can take a while.

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

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

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

так что просто найди себе нормальную команду, ггг ))

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

компилятор все такие конструкции игнорит и расставляет как ему больше хочется

Чем точнее ты расскажешь компилятору о том, что ты хотел сделать, тем более обоснованно он сможет принимать решения на этапах оптимизации и кодогенерации - эта простая мысль в голову не приходила?

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

Какой более сильный аргумент за использование unique_ptr в пимпле ты ещё можешь привести? :-)

#include <iostream>


bool badLog = true;

class BadLogException : std::exception {

};

void myCoolLog(const std::string& s) {
    if (!badLog) {
        std::cout << s << std::endl;
    } else {
        throw BadLogException();
    }
}

class AAImpl {
public:
    ~AAImpl() { std::cout << "Deleted" << std::endl; }
};

class AA {
public:
    AA() {
        impl = new AAImpl;
        myCoolLog("Created pimpl object at AA()");
    }
    ~AA() {
        delete impl;
    }

private:
    AAImpl* impl;
};

int main(int argc, char *argv[])
{
    try {
        AA a;
    } catch (...) {
    }
    return 0;
}

Сценарий не сказать, чтобы особо вероятный, но в нелёгком деле командной разработки ни от чего зарекаться нельзя.

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

QtCreator ломается, если ты пытаешься посмотреть функцию, для которой QtCreator не нашел исходнике в cmake (исходник генерируется). Или как-то так. В этом случае QtCreator эпично зависает на пару минут.

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

Т.е. найти объявление локальной переменной в методе для вас проблема?

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

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

Почему исчезли? Не исчезли. На практике ты не будешь смотреть объявление handle_halign, на это обычно времени нет. Ты прикинешь, что делает ф-я из контекста и по названию, потом ВНЕЗАПНО окажется что она зависит от переменной из внешнего контекста (этой информации нету ни в названии, ни в типе, ни по смыслу, был бы ты не идиотом, передавал бы этот параметр vertical третьим аргументом, но ты же так не сделал), которая меняется хз как, хз где и тоже совершенно неожиданным образом. В результате - либо надо прежде, чем менять этот код, досконально разбираться во всем контрол флоу (что резко повышает затраты, это ж будет, повторюсь, не одно место где ты там чето «нарефакторил», ака «обфусцировал»), либо надеяться, что код писал не баран и в handle_halign не будет потенциально опасных вещей. Но надежды не оправдаются и мы с нехилой долей вероятности получим весьма сложный в отладке баг.

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

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

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

Да, и прочитайте где-нибудь о плюсовых лямбдах, захватах контекста и пр. Чтобы не нести бред про какой-то внешний контекст. Заодно почитайте про локальные функции, дабы было понятно, в какой роли выступает handle_halign.

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

Это я потому и спросил. Есть у меня проект, вроде совсем небольшой, а clangcodemodel тормозит ощутимо. Недавно пробовал новый kdevelop, так вот там на том же проекте автодополнение без тормозов(хотя там тоже на основе clang автодополнение построено). Вот все мне в qreatore нравится, но вот можно ведь за столько лет сделать нормальную модель кода на шланге.

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

Принимай дозу живительной урины на ротешник, смайлофаг.

Какой более сильный аргумент за использование unique_ptr в пимпле ты ещё можешь привести? :-)

1) При исключении в конструкторе, std::unique_ptr<T> _impl автоматически удалится, T* _impl - нет. 2) std::unique_ptr<T> _impl автоматически запрещает конструктор копирования с оператором присваивания и генерирует конструктор перемещения с оператор перемещения. Для T* _impl все это надо писать руками. 3) std::unique_ptr гарантированно выдает ошибку при попытке удалить объект неполностью определенный типа ( а такая попытка это, между прочим, UB), для T* никаких гарантий нет, хотя и все более-менее адекватные компиляторы выдают warning.

нужно это сделать для сотни классов
сотни классов

Дважист в треде, все в абстрактный синглтон прокси фактори бин.

voivoid
()

Многое зависит от задачи. Если пишется какая-то гуйня с окнами - это очевидно, задача, описываемачя объектами, которые управляются событиями.

И здесь породить несколько классов и перекрыть нужные методы куда предпочтительнее, чем заводить кучу глобальных функций с длинными именами, дескрипторами, указателями на коллбеки, заполнять километровые структуры... Кто программировал на голом win32 API, тот меня поймёт.

Здесь код на C++ выглядит куда опрятнее, чем на C, и при этом сохраняет производительность нативной компиляции. Кресты на этом и поднялись - это очень удачный компромисс между высоким и низким уровнем.

В итоге болезный не знает током ни WinAPI, ни POSIX — ничерта.

Да-да, вот как человек, знающий, что такое трах с WinAPI, после которого получается ещё и код, прибитый к платформе, я предпочитаю писать на C++, да ещё и с привлечением Qt.

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

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