Наприклад, у минулого інструменту SysInternals "FileMon" є драйвер режиму ядра, вихідний код якого повністю знаходиться в одному 4000-рядковому файлі. Те саме для першої коли-небудь написаної програми, що колись написана (~ 2000 LOC).
Наприклад, у минулого інструменту SysInternals "FileMon" є драйвер режиму ядра, вихідний код якого повністю знаходиться в одному 4000-рядковому файлі. Те саме для першої коли-небудь написаної програми, що колись написана (~ 2000 LOC).
Відповіді:
Використання декількох файлів завжди вимагає додаткових накладних витрат. Потрібно налаштувати сценарій складання та / або makefile з розділеними етапами компіляції та зв’язування, переконатися, що залежність між різними файлами керована правильно, написати «zip» скрипт для легшого розповсюдження вихідного коду електронною поштою чи завантаження тощо. на. Сучасні IDE сьогодні, як правило, беруть на себе цей тягар, але я впевнений, що в той час, коли була написана перша програма ping, такого IDE не було. А для файлів, малих як ~ 4000 LOC, без такого IDE, який добре управляє кількома файлами, компроміс між згаданими накладними та переваги від використання декількох файлів може дозволити людям приймати рішення щодо підходу одного файлу.
Тому що С не добре в модуляризації. Він стає безладним (файли заголовків і #includes, зовнішні функції, помилки під час зв’язку тощо), і чим більше модулів ви вводите, тим складніше він отримує.
Більш сучасні мови мають кращі можливості модуляризації частково через те, що вони вчилися на помилках C, і вони спрощують розбивати вашу кодову базу на більш дрібні, простіші одиниці. Але з C може бути корисним уникнути або звести до мінімуму всю цю проблему, навіть якщо це означає згуртування того, що в іншому випадку вважатиметься занадто великим кодом в один файл.
Крім історичних причин, є одна причина використовувати це в сучасному програмному забезпеченні, чутливому до продуктивності. Коли весь код знаходиться в одній компіляційній одиниці, компілятор може виконати оптимізацію для всієї програми. За допомогою окремих блоків компіляції компілятор не може оптимізувати всю програму певними способами (наприклад, вклавши певний код).
Лінкер, безумовно, може виконати деякі оптимізації на додаток до того, що може зробити компілятор, але не всі. Наприклад: сучасні лінкери справді хороші у відведенні невизначених функцій, навіть у кількох файлах об'єктів. Вони можуть виконувати деякі інші оптимізації, але нічого подібного до того, що компілятор може робити всередині функції.
Одним з відомих прикладів модуля коду з одним джерелом є SQLite. Докладніше про це можна прочитати на сторінці « Зміна SQLite» .
1. Резюме
Понад 100 окремих вихідних файлів об'єднуються в один великий файл C-коду під назвою "sqlite3.c" і називається "об'єднання". У об'єднанні міститься все, що потрібно програмі, щоб вбудувати SQLite. Файл об'єднання має понад 180 000 ліній і розміром понад 6 мегабайт.
Об'єднання всього коду для SQLite в один великий файл спрощує розгортання SQLite - є лише один файл для відстеження. А оскільки весь код знаходиться в одній одиниці перекладу, компілятори можуть робити кращу міжпроцедурну оптимізацію, що призводить до машинного коду, який на 5% і 10% швидший.
$(CC) $(CFLAGS) $(LDFLAGS) -o $(TARGET) $(CFILES)
ніж перемістити все в один файл soudce. Ви навіть можете зробити компіляцію цілої програми як альтернативну ціль традиційному сценарію збірки, який пропускає перекомпіляцію вихідних файлів, які не змінилися, подібно до того, як люди можуть вимкнути профілювання та налагодження виробничої цілі. У вас немає такого варіанту, якщо все знаходиться в одній великій купу ресурсів. Це не те, до чого люди звикли, але в цьому немає нічого громіздкого.
На додаток до коефіцієнта простоти, про який згадував інший респондент, багато програм C написані однією особою.
Коли у вас є команда людей, бажано розділити додаток на кілька вихідних файлів, щоб уникнути безоплатних конфліктів у зміні коду. Особливо, коли над проектом працюють як просунуті, так і дуже молодші програмісти.
Коли одна людина працює сам, це не проблема.
Особисто я використовую кілька файлів на основі функції як звичну річ. Але це тільки я.
Тому що C89 не мав inline
функцій. Що означало, що розбиття файлу на функції спричиняє накладні витрати на натискання значень на стек та стрибки навколо. Це додало неабияких витрат на реалізацію коду в 1 великому операторі комутатора (циклі подій). Але цикл подій завжди набагато складніше здійснити ефективно (або навіть правильно), ніж більш модульоване рішення. Тож для великих проектів люди все ж таки відмовляться від модуляризації. Але коли вони заздалегідь продумали проект і змогли контролювати стан за допомогою заяви 1 перемикача, вони вибрали це.
Сьогодні, навіть на C, не потрібно жертвувати продуктивністю, щоб модулювати його, оскільки навіть C функції можуть бути вписані.
inline
у компіляторах C89 не було ключового слова, не вдалося вписати, тому вам довелося записати все в одну гігантську функцію, невірно. Ви майже ніколи не використовуєте inline
як оптимізацію продуктивності - компілятор, як правило, знає краще, ніж ви все одно (і може так само добре ігнорувати ключове слово).
inline
Ключове слово компоновщика пов'язаного з семантикою , які є більш важливими , ніж питання про те, слід виконувати в лінії оптимізацію, але деякі реалізації мають інші директиви для контролю якості в підкладці і такі речі іноді можуть бути дуже важливі. У деяких випадках функція може виглядати як занадто велика, щоб її варто було вкладати, але постійне складання може майже зменшити розмір та час виконання. Компілятор, який не має сильного поштовху, щоб заохочувати
Це вважається прикладом еволюції, про що я дивуюсь, досі не згадувалося.
У похмурі дні програмування складання одного FILE може зайняти кілька хвилин. Якби програма була модулізована, включення необхідних файлів заголовків (без попередньо складених параметрів заголовка) було б істотною додатковою причиною уповільнення. Крім того, компілятор може вибрати / потрібно зберегти деяку інформацію на самому диску, ймовірно, без переваги автоматичного файлу swap.
Звички, які ці фактори навколишнього середовища призвели до перенесення в постійну практику розвитку, з часом лише повільно адаптувалися.
На той час виграш від використання одного файлу був би подібним до того, який ми отримуємо за допомогою SSD замість жорстких дисків.