12 June 2012

Dead 666

На тему говнокода можно говорить и писать вечно. Говнокод в этой Вселенной бескраен, как просторы Индии. И каждый божий день день на поддержание этого культа работают легионы, даже более многочисленные, чем число контрибуторов ядра Linux...


Недавно имел на работе счастье столкнуться с чудесной библиотекой LIVE555, предназначенной для стриминга различного медиаконтента по Сети.
Написано все типа на C++. По факту -- используется горячо любимый многими огрызок "си с классами", и этот кусок говнокода есть отличная иллюстрация полной ущербности такого рода усечений языка.


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

Вот так вот выглядит сигнатура метода добавления нового элемента в таблицу:

void* HashTable::Add(char const* key, void* value) 
// и даже не спрашивайте меня, что тут нам возвращают

Очевидно, под видом void* вы можете хранить все, что душе угодно. Особенно удобно хранить всякие простые типы, а-ля int. Главное, не забывать их освобождать по мере необходимости. Или ладно -- ведь никто и никогда не помешает вам типкастить указатель в целое, верно? А ведь если у вас 64-х разрядная архитектура, так под видом указателя можно хранить даже double! Как удобно получается!
Отдельно можно написать целый трактат о типе "char const*" как об универсальном ключе для хэш хранилища. Особенно, если ваша таблица имеет еще волшебное поле "тип ключа", с магическими значениями типа ONE_WORD_HASH_KEYS, и тогда вы можете под капотом сравнивать ключи и так, и этак! Очень удобно!

Кстати, про "char const*". Про std::string аффторы библиотеки никогда не слышали.
Более того, что еще более удивительно, им даже не хватило смекалки придумать свой велосипед. Итого, вся программа просто усеяна "char const*", и кодом типа:

// A C++ equivalent to the standard C routine "strdup()".
// This generates a char* that can be deleted using "delete[]"
char* strDup(char const* str);


или

#define mediumNameMaxLen 30
class Medium {
  // ...
  char fMediumName[mediumNameMaxLen];
};


Сколько мужики приложили сил на борьбу с утечками памяти и порчей оной -- одному б-гу известно.

Любовь аффторов к "void*" безгранична.
К примеру, считается совершенно нормальной практикой описывать россыпь полей такого типа в public секции классов, и снабжать это убедительными комментариями типа

// a pointer to additional, optional, client-specific state

Но, на самом деле, это все мелочи и всего лишь жалкие тактические просчеты, которые блекнут перед стратегическим видением авторов библиотеки. Они не в курсе, что наследование вышло из моды еще лет 20 назад, поэтому к использованию предлагается ОЧЕНЬ развесистая иерархия, где даже самый простой класс является в седьмом колене потомком Абрама, который родил Исаака, который родил Иакова.
Интерфейсы? Какие интерфейсы?

Вот так вот выглядит это гавно с высоты птичьего полета


При этом волшебный базовый класс, под многозначительным названием Medium (очевидно, намекающим на то, кем надо быть, чтобы понять что и как здесь работает) содержит в себе такой вот набор методов:

virtual Boolean isSource() const;
virtual Boolean isSink() const;
virtual Boolean isRTCPInstance() const;
virtual Boolean isRTSPClient() const;
virtual Boolean isRTSPServer() const;
virtual Boolean isMediaSession() const;
virtual Boolean isServerMediaSession() const;
virtual Boolean isDarwinInjector() const;
// Да, мужики знают, что такое const, но никогда не слышали о типе bool...


Мысль понятна?

На этом все... пожалуйста, не приумножайте энтропию этой хрупкой Вселенной! Она и без вашей помощи развалится вся к ебеням!

No comments:

Post a Comment