Что именно делает препроцессор Arduino?

Arduino утверждает, что является «языком», а не просто «инфраструктурой приложений», и файлы Arduino имеют собственное расширение .ino. Язык, очевидно, C++, но не совсем. Насколько я понимаю, у Arduino есть какой-то специальный препроцессор, который преобразует файлы .ino в файлы C++ перед их компиляцией.

Мой вопрос: что точно делает этот препроцессор? В чем именно разница между «языком Arduino» и настоящим C++? В документации Arduino это, кажется, замалчивается.

В частности, со мной происходили странные вещи, когда я пытался определить свои собственные классы в своем скетче. Трудно понять, что я делаю не так, когда язык нигде не указан.

, 👍2

Обсуждение

Конвертер Arduino ino в cpp не затрагивает ваши файлы cpp и h. Он преобразует только файл ino в файл cpp, как описал Маженко в своем ответе., @Juraj

*Со мной происходили странные вещи* - можете ли вы привести пример?, @Nick Gammon

@NickGammon Это было давно, поэтому я не помню точное сообщение об ошибке. Но я подозреваю, что это было вызвано автоматически созданными прототипами. (т.е. функция принимает структуру или класс в качестве аргумента, а прототип вставляется перед объявлением этой структуры или класса), @user31708


2 ответа


Лучший ответ:

8

По сути, он делает четыре вещи:

  1. Он добавляет #include <Arduino.h> в начало вашего файла, что дает вам доступ ко всем классам, функциям и определенным переменным/макросам API.
  2. Он объединяет все файлы INO в один монолитный файл (в том же порядке, что и вкладки в окне),
  3. Он сопоставляет записи #include с библиотеками и добавляет файлы из этих библиотек в список файлов для компиляции, и
  4. Он сканирует ino-файлы в поисках функций и добавляет к ним прототипы в начало вашего файла.

Последнее может вызвать проблемы. Исторически сложилось так, что прототипы никогда не помещались в нужное место, и если вы когда-нибудь передали в функцию структуру, придуманную вами самим, она бы ужасно сломалась. Сегодня он работает лучше, но все еще не идеален на 100 %.

По сути, это означает, что вам не нужно придерживаться правила C/C++ «Вы должны определить это, прежде чем использовать». Что, конечно, делает программистов ленивыми.

,

и он объединяет все ino-файлы проекта в один файл, начиная с ino-файла с тем же именем, что и у папки проекта, а затем остальных ino-файлов в алфавитном порядке (это тот же порядок, что и вкладки в IDE), @Juraj

Ах да, это тоже., @Majenko


5

См. мой ответ: Как IDE организует вещи

Я не уверен, что ответы, содержащие только ссылки и относящиеся к ссылке Stack Exchange, приемлемы. Если это не так, вот первая часть ответа:

Вот как IDE организует ваш «скетч»:

  • Основной файл .ino имеет то же имя, что и папка, в которой он находится. Итак, для foobar.ino в foobar папка — основной файл foobar.ino.
  • Все остальные файлы .ino в этой папке объединяются в алфавитном порядке в конце основного файла (независимо от того, где находится основной файл, в алфавитном порядке).
  • Этот объединенный файл становится файлом .cpp (например, foobar.cpp) — он помещается во временную папку компиляции.
  • Препроцессор «услужливо» генерирует прототипы функций, которые он находит в этом файле.
  • Основной файл сканируется на наличие директив #include <libraryname>. Это заставляет IDE также копировать все соответствующие файлы из каждой (упомянутой) библиотеки во временную папку и генерировать инструкции для их компиляции.
  • Любые файлы .c, .cpp или .asm в папке скетча добавляются в процесс сборки как отдельные единицы компиляции (которые то есть они компилируются обычным способом в отдельные файлы)
  • Все файлы .h также копируются во временную папку компиляции, поэтому на них можно ссылаться в файлах .c или .cpp.
  • Компилятор добавляет в процесс сборки стандартные файлы (например, main.cpp)
  • Затем процесс сборки компилирует все указанные выше файлы в объектные файлы.
  • Если фаза компиляции прошла успешно, они скомпонуются вместе со стандартными библиотеками AVR (например, предоставив вам strcpy и т. д.)

Побочным эффектом всего этого является то, что вы можете считать основной скетч (файлы .ino) по сути написанным на C++. Однако генерация прототипа функции может привести к неясным сообщениям об ошибках, если вы не будете осторожны.

,

Спасибо! Откуда вы узнали всю эту информацию?, @user31708

Наблюдение за тем, какие файлы копируются во временный каталог, и просмотр команд, выполняемых при включенной «подробной» компиляции., @Nick Gammon

Где находятся временные файлы? Можете ли вы настроить Arduino IDE так, чтобы их можно было легко просматривать?, @NeilenMarais

Если вы включите «подробную компиляцию», вы сможете увидеть, где находятся временные файлы., @Nick Gammon