Линус Торвальдс, создатель Linux и его неоспоримый авторитет, никогда не скрывал своего скептического отношения к языку C++ и его использованию в разработке ядра операционной системы. Его резкие высказывания на эту тему сопровождаются весомыми техническими доводами, которые заслуживают внимательного рассмотрения. Давайте разберёмся, что стоит за этой позицией, отбросив эмоции и сосредоточившись на сути аргументов.
C и C++: близнецы или всё-таки нет?
На первый взгляд, C и C++ кажутся родственниками: второй часто называют объектно-ориентированной версией первого. Однако правильнее считать C++ расширением C, которое привносит такие возможности, как классы, конструкторы, деструкторы, шаблоны, обработка исключений, пространства имён и перегрузка операторов. Эти дополнения делают язык более мощным, но вместе с тем усложняют его использование. Неудивительно, что именно в этих особенностях кроются основные претензии Торвальдса к C++.
Главные аргументы против C++
Свои взгляды Линус неоднократно излагал в списках рассылки ядра Linux, начиная с дискуссий ещё в 2004 году. Один из ключевых источников — обсуждение под названием «Компиляция модуля ядра на C++ и Makefile». Оставим в стороне личные выпады и сосредоточимся на сути его критики.
1. Проблемы с обработкой исключений
«Обработка исключений в C++ изначально ущербна. Особенно это касается ядер.»
В языке C ошибки традиционно сигнализируются через возвращаемые значения функций. C++ же активно продвигает механизм исключений, которые могут возникнуть в любой точке кода. Это делает поведение программы менее предсказуемым: исключения нарушают линейность выполнения и требуют совершенно иного подхода к управлению ошибками. Для ядра, где каждая мелочь должна быть под контролем, такая неопределённость — серьёзный недостаток.
Отладка кода с исключениями становится сложнее, чем в случае с простыми возвращаемыми значениями в C. Если внедрить исключения в ядро Linux, это приведёт к смешению двух разных подходов к обработке ошибок, что, скорее всего, растянется на годы переходного периода. Для проекта с 30 миллионами строк кода, работающего на миллиардах устройств, подобный риск недопустим. Даже при строгом тестировании и контроле качества полностью исключить ошибки невозможно, а нестабильность ядра — это угроза для всех его пользователей.
2. Скрытое управление памятью
«Любой язык или компилятор, который прячет управление памятью за кулисами, — плохой выбор для ядра.»
Одна из особенностей C++ — это RAII (Resource Acquisition Is Initialization), или автоматическое управление ресурсами через конструкторы и деструкторы. Это удобно, но создаёт скрытую нагрузку, которую компилятор берёт на себя. В ядре Linux управление памятью отточено до мелочей, и многие оптимизации уже выжимают из компиляторов максимум. Внедрение автоматизации в этой области может замедлить работу модулей и добавить зависимость от компилятора.
Пусть эта зависимость кажется незначительной, в масштабах огромного проекта она становится ощутимой проблемой. Для ядра, которое должно быть быстрым и надёжным на любом оборудовании, даже малейшее снижение производительности или усложнение структуры — это шаг назад.
3. Объектная ориентация: нужна ли она?
«Объектно-ориентированный код можно писать и на C, без всей этой ерунды, что есть в C++.»
C++ часто выбирают ради объектно-ориентированного программирования (ООП), которое обещает упростить разработку через модульность и повторное использование кода. Однако Торвальдс утверждает, что эти преимущества не стоят риска. Более того, он уверен, что базовые принципы ООП можно реализовать и в C, используя структуры (structs) вместо классов. Вот простой пример:
#include <stdio.h>
#include <stdlib.h>
// Определяем "класс" через структуру
typedef struct {
int value;
void (*increment)(struct Person *self); // Указатель на функцию
} Person;
// Реализация метода
void increment_person(Person *self) {
self->value++;
}
// "Конструктор"
Person* create_person(int initial_value) {
Person *p = (Person*)malloc(sizeof(Person));
p->value = initial_value;
p->increment = increment_person;
return p;
}
// "Деструктор"
void destroy_person(Person *p) {
free(p);
}
int main() {
Person *p = create_person(5);
printf("Начальное значение: %d\n", p->value);
p->increment(p);
printf("После увеличения: %d\n", p->value);
destroy_person(p);
return 0;
}
ООП в ядре Linux — это не техническая необходимость, а вопрос удобства разработчиков. Но ядро славится не комфортом программистов, а своей скоростью и стабильностью. Внедрение ООП ради эргономики неизбежно ослабит эти ключевые качества. Торвальдс видит в этом не просто риск, а изменение философии проекта, что вряд ли обрадует пользователей, особенно в критически важных системах.
4. Нестабильность библиотек
«Библиотеки вроде STL и Boost приносят бесконечные проблемы, когда что-то идёт не так. И не верьте тем, кто говорит, что они стабильны и переносимы — это просто чушь.»
Для приложений уровня пользователя STL (Standard Template Library) и Boost могут считаться стабильными. Но в контексте ядра Linux понятие «стабильность» куда строже. Внедрение таких зависимостей снова ставит целью удобство разработчиков, но ценой производительности и надёжности. К тому же каждая новая зависимость передаёт часть ответственности её maintainers, что чревато рисками, такими как недавний инцидент с бэкдором в liblzma (CVE-2024–3094).
5. Абстракции, которые мешают
«Абстрактные модели программирования через пару лет оказываются неэффективными, но переписать код уже невозможно без полной ломки приложения.»
Этот довод касается не только C++, но и ООП в целом. Шаблоны проектирования помогают решать типичные задачи, но неправильно построенная иерархия классов может привести к неуправляемому коду. Даже опытные разработчики ядра не застрахованы от таких ошибок. В проекте с миллионами строк кода это может обернуться необходимостью полной переработки архитектуры — роскошь, которую Linux себе позволить не может.
6. В итоге всё равно пишешь на C
«Единственный способ писать эффективный и переносимый код на C++ — ограничиться тем, что уже есть в C.»
C++ не заставляет использовать все его возможности. Можно писать на нём в стиле C, но тогда в чём смысл? Если отказаться от исключений, шаблонов и ООП, C++ становится лишь избыточным инструментом. К тому же, выбор C привлекает разработчиков, которые понимают низкоуровневые детали и не отвлекаются на красивые, но ненужные абстракции.
А что дальше? Rust или Java?
Недавно в сообществе заговорили о Rust для ядра Linux. Следующими на очереди могут оказаться Go или даже Java с компиляцией в нативный код через GraalVM. Эти идеи понятны: разработчики хотят упростить себе жизнь. Но Линус твёрдо стоит на своём: ядро на 99% состоит из C и 1% ассемблера, и добавление новых языков только усложнит его чистую архитектуру.
Так оправдан ли отказ от C++?
Однозначного ответа нет. Для обычных приложений вроде графического редактора доводы Торвальдса звучат смешно. Но в мире ядра, где каждая строка кода критически важна, они обретают вес. Linux обязан своей популярностью скорости и надёжности, достигнутым благодаря строгой приверженности C. Любые эксперименты с C++ или другими языками могут пошатнуть эти основы.
Уроки для нас
Отказ от C++ учит нас выбирать инструменты с умом. Linux — это уникальный проект, где 30 миллионов строк кода работают на миллиардах устройств. Его успех — результат дисциплины и фокуса на главном. Следующий раз, когда коллега предложит переписать ваш проект на новомодном языке, подумайте: это нужно пользователям или просто вам?
Вместо заключения
Представьте, что вы в больнице, и вас загружают в аппарат МРТ. Хотите ли вы, чтобы его ядро могло выбросить исключение? Linux сегодня везде — от смартфонов до спутников и медицинских приборов. Рисковать его стабильностью ради удобства — значит играть с огнём. Линус, возможно, и ворчит, но его вопрос остаётся актуальным: это круто или действительно необходимо?
***✨ А что думаете вы? ✨
Делитесь мыслями в комментариях — ваше мнение вдохновляет нас и других!
Следите за новыми идеями и присоединяйтесь:
• Наш сайт — всё самое важное в одном месте
• Дзен — свежие статьи каждый день
• Телеграм — быстрые обновления и анонсы
• ВКонтакте — будьте в центре обсуждений
• Одноклассники — делитесь с близкими
Ваш отклик помогает нам создавать больше полезного контента. Спасибо, что вы с нами — давайте расти вместе! 🙌