82 / 2 / 0
Регистрация: 10.02.2024
Сообщений: 81
|
|
1 | |
Для чего нужны промежуточные фалы *.o/*.obj при компиляции программы на с/с++? Как работает компилятор?13.08.2024, 16:54. Показов 439. Ответов 18
Метки нет (Все метки)
Добрый день.
Углубляюсь в изучение С. Дошел до темы работы компилятора. Правильно ли я понимаю назначение промежуточных файлов objective и вообще процесса компиляции программы?: 1) Препроцессор заменяет все команды препроцессора в файле Program.c на текст. (Либо это какие-то будут значения, либо с помощью всяких #include в наш файл поместится код других файлов и библиотек) 2) Компилятор превращает наш файл Program.c в уже почти рабочую программу Program.obj. В описании сказано, что в этот момент все отдельные файлы и библиотеки нужные нашей программе превращаются в отдельные фалы.obj, но я не совсем понял этот момент. Ведь мы уже на этапе препроцессора поместили все библиотеки и другие фалы в наш файл Program.c. О каких тогда нескольких файлах.obj может идти речь? 3) Линковщик создает связи между файлами.obj (как я понял это как раз связи по типу "из основной программы вызываем выполнение какой-нибудь функции библиотеки", но опять же, вопрос по предыдущему пункту) и все фалы.obj объединяет в финальный исполняемый файл программы.
0
|
13.08.2024, 16:54 | |
Ответы с готовыми решениями:
18
Мне нужны программы для компиляции( извените что сюда написал!) Нужно разобраться со структурой программы. Для чего здесь нужны глобальные переменные? Что они делают? Для чего нужны ограничения при использовании Instance Откуда можно скачать компилятор для obj-c под Windows? |
453 / 237 / 59
Регистрация: 07.01.2023
Сообщений: 956
|
|
13.08.2024, 19:31 | 2 |
Кроме написанного вами кода ничто в .o не превращается. В библиотеках и так уже .o лежат
Если у вас проект состоит больше чем из одного файла (а нормальные проекты так и выглядят), то для каждой единицы трансляции генериться свой .o файл Не совсем так, не между файлами, а собирает используемые функции из файлов и библиотек, добавляет при необходимости startup код, распихивает все по нужным секциям.
1
|
Модератор
8941 / 6708 / 920
Регистрация: 14.02.2011
Сообщений: 23,645
|
|
13.08.2024, 19:38 | 3 |
Компилятор переводит с языка высокого уровня ( В данном случае C++) на язык машинных кодов, грубо можно сказать что ассемблер, но это не ассемблер. Например ассемблер инструкция
NOP а в машинном коде это код 0x90( пример из Intel то что на память помню)не только он еще и создает связи переделывает условные(безусловные) переходы на конкретные константы(числа) Найди где-нибудь дизассемблер рекомендую IDA (был а может и есть бесплатный) напиши простенькую программу, лучше на С++, а не на ардуино скомпилируй её, и дизассемблируй. Куча вопросов отпадет, правда потом появятся другие но это совсем другая история
1
|
82 / 2 / 0
Регистрация: 10.02.2024
Сообщений: 81
|
|
13.08.2024, 23:38 [ТС] | 4 |
Это, вроде, понял. Звучит логичнее и стыкуется с другим описанием компиляции. Спасибо.
А, выходит, вот он этот момент. Компилятор превращает все что упоминалось в программе в файлы.obj (кроме системных библиотек, которые для оптимизации уже скомпилированы), а потом на этапе линковки он как раз отбрасывает все не неужное и оставляется только те блоки кода, которые реально где-то используются? Добавлено через 11 минут Да, с асемблером немного работал и даже успел пару своих программ дизасемблировал, смотрел как выполнение программы двигается по 16-ричным кодам команд и изменяются значение регистров, но что-то быстро утомился и решил пока в ассемблер не лезть). Пока только куча вопросов появляется после такого . Сейчас, так сказать, пока просто решил на уровень ниже с с++ опуститься, чтобы научиться писать те же программы но, с меньшим уровнем абстракций. После может и к ассемблеру серъезнее перейду. Хотя, как понял из описаний, сейчас С это все-таки самый оптимальный вариант между скоростью разработки и близостью к железу)
0
|
Модератор
|
|
14.08.2024, 00:54 | 5 |
Правда канал по движку Unreal Engine, но в серии видео где будет писаться свой движок, структурой похожие на UE автор решил начать с подробного разбора процесса компиляции. И еще на примере Visual Studio все делается
По сути компиляцию можно разделить на этапы: - препроцессирование, на выходе файл .i в файл подставляются все #include и #define, раскрываются #if удаляются комментарии и прочее, вроде на этом этапе еще происходит кодогенерация (например раскрытие шаблонов), можно посмотреть что получается получив файл с этого этапа, есть спец флаги - трансляция, перевод в ассемблерный код, результат тоже можно посмотреть получив файл, есть спец флаги - ассемблирование, перевод в машинные коды, тут уже получение .o/.obj файлов - линковка, то есть сборка исполняемого файла, на винде либо .exe либо .dll lib файлы вроде не линкуются, так как это по сути архив с obj внутри еще по пути происходят разного рода оптимизации и проверки на корректность кода Зачем так низко? На чистом Си почти ничего нету и все надо делать самому. В этом плане С++ не проигрывает в плане близости к железу, но зато выигрывает в скорости разработки. Да и по хорошему выход ассемблера при решении одной и той же задачи на Си и С++ в ООП стиле будет очень похожим
1
|
82 / 2 / 0
Регистрация: 10.02.2024
Сообщений: 81
|
|
14.08.2024, 01:11 [ТС] | 6 |
У меня основной род деятельности это программирование микроконтроллеров. Начал с С++, но понял что освоить С
тоже необходимо по как минимум трем причинам: 1) Столкнулся с конфликтом, где некоторый чужой код написанный на С, но использующий те же ключевые слова и тот же синтаксис как С++ просто не компилируется, т.к. тот же синтаксис уже имеет какое-то другое применение. По этому мне нужно изучить С и понимать как заставить работать код С в С++ и как реализовать код С++ на С. 2) Для микроконтроллеров предпочтительнее С, т.к. С++, по сути, избыточен. В будущем уже знаю, что придется переходить на другие архитектуры МК, где большая часть примеров и кода на писаны на С и не хочу нарушать традиции). 3) Изучать как все работает с низу - это круто. Кто бы что не говорил, но в моей практике, чем больше я углубляюсь как работает код на уровне железа и системы - тем лучший код я начинаю писать и на высоком уровне (всякие приложения и программы). Поэтому это скорее как хобби и желание понять что-то сложное, нежели действительная необходимость в 2024 . Хочется не просто применять какие-то решения потому что кто-то где-то сказал, что так лучше. А проверить все самому, убедиться в этом и понять почему)
0
|
82 / 2 / 0
Регистрация: 10.02.2024
Сообщений: 81
|
|
14.08.2024, 05:41 [ТС] | 8 |
Не совсем понял мысль. Я утверждаю, что для МК больше подходит С, чем С++. А ты сначала оспариваешь меня, а потом как будто оспариваешь себя.
Так что по твоему мнению больше подходит для МК С или С++?)
0
|
453 / 237 / 59
Регистрация: 07.01.2023
Сообщений: 956
|
|
14.08.2024, 05:50 | 10 |
Для МК больше подходит то, что вы лучше знаете. Хоть на Java пишите c использованием NanoVM.
1
|
3968 / 2512 / 422
Регистрация: 09.09.2017
Сообщений: 11,108
|
|
14.08.2024, 10:09 | 11 |
Сообщение было отмечено Elesh_Makfa как решение
Решение
Не знаю о каких "файлах .obj" говорите вы, но компилятор из каждого .c файла делает .o файл. Преобразует текст на языке Си в машинные коды, но пока не проставляет адреса меток.
Линковщик складывает все .o файлы в один исполняемый файл и вот на этом этапе прописывает адреса. Компилятор работает за раз только с одним .с файлом. Представьте, что функция из одного .с файла вызывает функцию из другого. На языке Си у функций есть имена, но в машинных кодах они не сохраняются, там есть только адреса. Но пока идет компиляция .с файла этот адрес неизвестен, поэтому компилятор оставляет там заглушку. А потом приходит линкер, слепляет все .о файлы в один бинарник. Теперь у каждой функции есть фиксированный адрес, который и можно прописать на место заглушки. Ассемблер лучше изучать на микроконтроллерах. Там он более по-людски сделан. Да и сами программы там проще. Плюс сама платформа менее раздутая и более документированная. Странный вопрос. Например, потому что человек хочет разобраться как же на самом деле работает машина. Elesh_Makfa, для этого микроконтроллеры тоже подходят лучше. Не секрет каких? Нет. Он говорит, что на С++ можно программировать более эффективно (и по скорости разработки, и по скорости выполнения, и по читабельности, и по объему прошивки), чем на Си. В теории. Вот только придется глубоко изучить соответствующие возможности языка и очень аккуратно ими пользоваться. Лично для меня это слишком сложно, поэтому предпочитаю Си и макросы.
1
|
82 / 2 / 0
Регистрация: 10.02.2024
Сообщений: 81
|
|
14.08.2024, 12:30 [ТС] | 12 |
Как я понял, компилятор создает objective фалый. В unix они имеют расширение .o, а в windows .obj.)
AVR (углубился от Arduino). Да, еще не STM, но уже написание своих библиотек, доработка стандартных и работа с регистрами)). А вот таких мнений еще не встречал. Любопытно). В плане того, что С++ может быть эффективнее на МК. Но, да, я, тоже всего прочитанного в интернете я решил, что лучше будет все-таки освоить С. Тем более, что мне жутко любопытно, как же с помощью структур реализовывать классы))
0
|
Модератор
|
|
14.08.2024, 12:40 | 13 |
На винде зависит от компилятора. Если gcc/mingw то так же .o/.a, если студия то .obj/.lib а если clang то простой как у mingw а у clang-cl как у студии
Про другие компиляторы не в курсе, например Builder, Intel Не стоит заниматься такими извращениями. Если нужно ООП, то тогда стоит использовать С++ и его Си-шную часть вместо STL
0
|
14.08.2024, 12:44 | 14 |
Elesh_Makfa,
Эффективнее можно быть не только скорость выполнения, но и скорость написания, корректность, избегание ошибок явных и неявных. То, что в C вы можете написать и потом надеяться не забыть, чтобы не ошибиться, в C++ можно поставить на контроль компилятору. И все возможности и библиотеки использовать не обязательно. Особенно те, которые для МК не подходят. Однако, это не запрещает язык вообще. Я как-то раз использовал классы. Затем перевёл их на структуры, самопальную реализацию классов. Потом обратно на классы. Этот гемор того не стоит.
0
|
82 / 2 / 0
Регистрация: 10.02.2024
Сообщений: 81
|
|
14.08.2024, 13:19 [ТС] | 15 |
Странно. Я на винде давно не был, но год назад, из консоли компилировал сpp файл, ам промежуточные .obj точно были
Я это не как окончательно готовое решение хочу использовать. Пока цель только освоить это, понять. Потом уже по опыту буду решать что мне больше подходит. Это как хобби. Потом уже, когда попробую и то и то, создам тему обсуждения что лучше то или то. Но, в рамках программирования МК, опять же, повторяюсь, не раз столкнулся с кодом написанным на С и не понимаем его. Там-то мне один приятель и поведал, что оказывается когда еще не было ООП, классы релализовывали на структурах и в этом коде это и используются. Поэтому мне хоть как придется научится всем этим "извращениям" на С. Иначе дальше ардуино так и не уйдешь.
0
|
453 / 237 / 59
Регистрация: 07.01.2023
Сообщений: 956
|
|
14.08.2024, 13:28 | 16 |
Если на Pure C, то с помощью указателей на функцию, и макросов, если на C++ то есть классы. Но делать это на Pure C да еще и под МК нет ни малейшего смысла.
0
|
3968 / 2512 / 422
Регистрация: 09.09.2017
Сообщений: 11,108
|
|
14.08.2024, 13:33 | 17 |
В AVR отличный ассемблер. Рекомендую с ним ознакомиться, если еще не сделали этого. Не для того, чтобы использовать в повседневной работе, естественно, а чтобы прочувствовать как контроллер работает, как переменные превращаются в напряжения на ножках. Ну и чтобы без страха смотреть дизассемблерный выхлоп.
Может. Но, повторяю, нужно будет здорово изучить шаблоны, да и вообще соблюдать осторожность при программировании. Я вот не осилил. Криво и некрасиво. Си плохо подходит для работы с классами. Да и в контроллерах классы не слишком-то нужны. Да в Си тоже почти все можно повесить на компилятор, но зачастую это оказывается довольно сложно и никто этого не делает. Это важный момент, о котором и я говорил, когда упоминал осторожность. В С++ много библиотек, да и других возможностей, написанных для упрощения разработки на ПК. Но для МК накладные расходы оказываются слишком большими. Скажем, обычная работа со строками будет приводить к постоянным перевыделениям памяти. В общем, первой проблемой будет освоить одни возможности языка, а второй - удержаться от использования других. Добавлено через 3 минуты От компилятора и среды сборки зависит. Не удивлюсь если существуют такие, которые не генерируют объектников вообще. Смотря какие возможности объектов нужны. Так-то классическая реализация объектной модели в Си заключается всего лишь в передаче "объекта" первым аргументом в соответствующие функции. Как, например, в fprintf делается. Или gtk, как более полная реализация объектов.
0
|
Модератор
|
||||||||||||||||||||||||||
14.08.2024, 14:27 | 18 | |||||||||||||||||||||||||
Elesh_Makfa, Кстати, есть такой язык, как Objective-C, правда он яблочный (считается языком Apple и для macOS/iOS, но уже устаревшим, замененным на Swift), но по сути можно на нем писать и на других ОС. Это по сути Си с классами, расширение языка Си (а не как С++, который отдельный язык, а в Obj-C любая программа на Си является корректной), еще помимо классов есть некое подобие замыканий/лямбд, хотя это можно добавить и к чистому Си в виде Blocks Runtime
Компилировать Objective-C может Clang и как оказывается GCC (не знал раньше, но там вроде нету поддержки ARC). На платформах отличных от яблочной нету рантайма оригинального, но с этим помогает GNUStep (есть даже в версии для MSVC). А так у Clang по умолчанию есть поддержка и возможность компилировать 4 языка не зависимо от платформы, это C, C++, Objective-C и Objective-C++ (это по сути не язык а набор правил для совмещения языков Objective-C и C++) Язык прикольный, но довольно многословный и необычный. Вот пример ООП кода
И я еще не нашел онлайн компилятора с поддержкой ARC, либо пишет ошибки на флаг -f-objc-arc, либо ошибки не пишет, но не пишет ошибки на retain/release/autorelease и не удаляет объекты. Похоже онлайн компиляторы используют GCC Интересно впечатление о языке с приведенных примеров. Можно еще привет мир в виде без ARC
Добавлено через 21 минуту И пример кода на Си с Blocks
Blocks это тоже встроенная функция CLang, но опять же без рантайма, рантайм в коде Clang есть, но он не собирается по умолчанию. Но вполне подходит уже собранная версия, либо можно собрать самому, благо там всего 5 фалов исходных
0
|
453 / 237 / 59
Регистрация: 07.01.2023
Сообщений: 956
|
|
14.08.2024, 14:50 | 19 |
Самое непривычное в нем - это вызов методов через сообщения. Эдакий полный safe.
0
|
14.08.2024, 14:50 | |
14.08.2024, 14:50 | |
Помогаю со студенческими работами здесь
19
Для чего необходимо распределять память при помощи new и как оно работает Триггеры, вьюеры. Объясните, как их создавать, для чего нужны Для чего нужны (и как подобрать) эмиттерные резисторы в дифференциальном усилителе? Для чего нужны указатели на члены-функции класса и как их делать? Найти ошибку зацикливается ввод (при компиляции GUI, а при компиляции CONSOLE - работает) Ошибка при компиляции проекта из Builder 2010 в XE3 — Unable to Open file 'ALIASREC.OBJ' Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |