LINUX.ORG.RU

Системное программирования.

 , ,


4

5

Только знакомлюсь с системный программированиям в среде Линукс. Сейчас читаю книжку Роберта Лав «Системное программирования» (1 издания Питер 2008). Знаю, что уже есть 2 издания, но пока в интернете оно на анг., а покупать не хочу. ( С английским туго. ) Может у кого есть скан 2 издания?

В этой книжке идется о программировании на Си и соответственно есть проблемы с С++.

Я понимаю, что программист С++ должен знать Си, но ...

Есть какая нибудь хорошая книжка о системном программировании С++? Или лучше книжка, где проводится сравнения системного программирования Си и С++?

Чтобы параллельно ее читать вместе с Робертом Лав.



Последнее исправление: beastie (всего исправлений: 3)
Ответ на: комментарий от Eddy_Em

ООП для свистоперделок нужно. Ему в системном программировании места нет. Зачем излишнее усложнение?

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

FILE* f=fopen("out.txt", "w");
fprintf(f, "Hello world\n!");
fclose(f);

или же (ну некий условный C++ подобный абстрактный код)

FILE* f=new FILE("out.txt", "w");
f->fprintf("Hello world!\n");
delete f;

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

ИМХО, если Страуструп откроет доступ напрямую к vtable классов, а C++ ABI стандартизируют (чтобы линковка с разными компиляторами не превращалась в ад), то преимуществ у всяких извращений в стиле GLIB просто не останется. С другой стороны, проблем такое изменение создаст значительно больше, чем существует сейчас...

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

Помимо объектов у ООП есть еще много каких вещей. И я уже неоднократно с пытающимися мне "доказать", что на сях тоже ООП есть, спорил, что таки тупо "объекты" — не есть ООП. Где наследование? Где полиморфизм?

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

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

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

Вы привели два варианта кода. Какая между ними разница? Ясно что ООП и без. Вообщем С++ дает возможность писать так и так. Как писать тогда? Мне удобней 1 вариант, но второй более смахивает на плюсы.

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

на сях тоже ООП есть, спорил, что таки тупо «объекты» — не есть ООП. Где наследование? Где полиморфизм?

Посмотри как сделали в GLIB. ИМХО, элитный пример того что мы говорим «C++ - это кака», а при этом изобретаем не менее костыльное ООП на сишечке.

Полифорфизм - это по сути указатель на функцию. В случае с C++ указатели на функцию «скрыты» под капот и добраться до них нереально. Хз почему Страуструп это не открыл, видимо оверхеда не было, а от проблем типа «Pure virtual function call» это спасало (в стандартном C++ без перделок это кажется нельзя воспроизвести).

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

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

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

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

О да! Спроектировать ООП-программу чисто на классах у меня не разу не получилось. Но без std::vector/std::map, а также без всяких std::string/QString/QByteArray мне жизнь уже не мила :)

Алсо, в некоторых задачах без ООП (или хотя бы без объектного программирования) ну просто никак. Я с гуем много работаю, ни одной библиотеки чисто на функциях пока что не видел. Все имеют яркую склонность к ООП. Так что видимо без него никак.

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

Ода! посоны, пишущие quemu такие тупые, жаль им эдди глаза не открыл раньше, они то во все поля ... Но эдди то лучше знает.

вот тебе ссылочка с наследованием и кастами.

http://code.metager.de/source/xref/qemu/include/qom/object.h

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

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

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

Ну конкретно с stdio второй вариант еще придется изобрести... :) Хотя, есть вероятность, что ассемблерный код обоих вариантов получится вообще идентичным. На мой взгляд - однозначно вариант на C, т.к. иначе в проект будет втянута C++ подобная либа (или просто пара cpp/h файлов), которая никакай полезной работы не делает, а только увеличивает энтропию вселенной...

ООП обычно существенно сокращает использование кода в ключевых местах программы. Классы получаются сложными, но их использование может оказаться проще, чем писать код напрямую. Экономия в 3 строчки в ключевом месте программы приведет к паре лишних файлов с классами на 100-1000 строк в проекте (и суммарный код проекта увеличится).

Например, не вижу смысла определять свой класс для работы с сокетами просто чтобы было ООП. Но, если нужно 3-4 немного разных TCP-сервера в одной программе с немного разной логикой работы с входящими подключениями, то профит от ООП есть. Также есть профит в определении класса типа TThread, от которого нужно унаследоваться и переопределить только одну функцию run. Если потоки будут в 5 местах в программе, то это очень компактно и красиво (проще чем работать со всякими pthread_init_attr напрямую).

В принципе, вместо классов тут можно использовать функции. Но если приходится по 5 параметров передавать в функции несколько раз, или использовать указатели на CALLBACK-функции, то проще классы.

Также исключения помогают сократить код обработки ошибок при вводе/выводе. Например, стиль java при работе с исключениями мне очень понравился: ни одной ошибки ввода/вывода не будет пропущено даже случайно, после каждого вызова функции не нужно проверять результат. Код обработки будет в одном месте в except (ну может в двух местах). А проверка на ошибки и генерация исключений сделаны в самой функции. Если идет активная работа с файлом/сокетом, то намного компактнее исключения, а не if после каждого вызова. Ради такого стоит заморочится с классом (хотя он и может получится в 1000 строк).

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

и добраться до них нереально

Добраться-то реально... Это ж С++ :) Только толку от этого немного, но если очень хочется или руки чешутся... Например, пора выстрелить в ногу, нога сама не отстрелится... Еще Саттер расказывал N способов обойти модификаторы доступа, чуть более изящные, чем тупое кастование яблок к апельсинам. И пюре виртуал калл невьехавшие в ООП в сплющеной реализации получают регулярно. (Достаточно посмотреть платиновые треды StackOverflow)

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

Например, не вижу смысла определять свой класс для работы с сокетами просто чтобы было ООП

Смысел обычно, чтоб не переписывать с POSIX на WSA и не засорять код оберточными макросами/вилками условной конпеляции. Да еще потом отдельно пристегивать их к epoll/iocp. Некоторые щас юзают просто boost asio и не парятся слоями абстрагирования от конкретной реализации. (И еще ждут затаскивания этого в std :) Потоки уже там, чо, пусть сокеты и io тоже будут)

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

И много того ООПа в Tk?

При желании даже в Haskell можно найти ООП не выходя за рамки функций и каррирования :) А если упоротся, то ООП даже в bash'е мерещится...

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

Где наследование?

Ахтунг, вещества. Да пожалуйста:

typedef struct base_t {
    int a, b;
};

typedef struct derived_t {
   int c;
   base_t base; 
};

void foo(base *b) {
    if (b) {
        printf("a: %d b: %d\n", b->a, b->b)
    }
}

int main() {
    derived_t d = { 3, { 2, 1 } };
    foo(d->base);

    return 0;
}

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

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