1.17 Инструкции препроцессора и директивы компиляции в 1С
❓ 1.17 Инструкции препроцессора и директивы компиляции в 1С: в чем разница и как они работают вместе?
📚 Документация
Заголовок раздела «📚 Документация»ИТС: Платформа — Глава 4. Встроенный язык — https://its.1c.ru/db/v8327doc
ИТС: Различие инструкций препроцессора и директив компиляции — https://its.1c.ru/db/v8327doc/bookmark/dev/TI000000116
🧠 Краткая теория
Заголовок раздела «🧠 Краткая теория»Зачем вообще нужны эти механизмы
Заголовок раздела «Зачем вообще нужны эти механизмы»Инструкции препроцессора и директивы компиляции нужны для того, чтобы в скомпилированном модуле остался только тот код, который действительно должен присутствовать в конкретном контексте.
Но действуют они на разных уровнях.
Инструкции препроцессора
Заголовок раздела «Инструкции препроцессора»В коде 1С часто встречается такое:
#Если Сервер Или ТолстыйКлиентОбычноеПриложение Или ВнешнееСоединение Тогда
#Если НЕ МобильныйАвтономныйСервер Тогда
#Если МобильныйКлиент ТогдаЭто инструкции препроцессора.
Они:
- действуют на исходный текст модуля
- исключают текст, который не должен присутствовать в данном контексте
- фактически «вырезают» части исходного кода еще до компиляции
📌 То есть препроцессор работает именно с текстом модуля.
Директивы компиляции
Заголовок раздела «Директивы компиляции»Кроме инструкций препроцессора, в 1С есть и директивы компиляции.
Примеры:
&НаКлиенте&НаСервере&НаСервереБезКонтекста&НаКлиентеНаСервереБезКонтекста&НаКлиентеНаСервереДирективы компиляции действуют не на произвольный текст, а на структурные единицы программного кода:
- процедуры
- функции
- объявления переменных
📌 То есть директивы определяют, какие методы и переменные попадут в конкретный экземпляр модуля.
Различие инструкций препроцессора и директив компиляции
Заголовок раздела «Различие инструкций препроцессора и директив компиляции»Инструкции препроцессора:
- работают с исходным текстом модуля
- исключают ненужные фрагменты до компиляции
Директивы компиляции:
- работают со структурными единицами кода
- влияют на состав конкретного экземпляра модуля на этапе компиляции
Инструкции препроцессора работают с текстом модуля,
а директивы компиляции — с методами и объявлениями переменных.
Как директивы компиляции и инструкции препроцессора работают вместе
Заголовок раздела «Как директивы компиляции и инструкции препроцессора работают вместе»На практике эти два механизма часто используются одновременно.
Логика такая:
- сначала для конкретного контекста определяется, какие инструкции препроцессора считаются истинными
- затем из исходного текста модуля исключаются неподходящие фрагменты
- после этого оставшийся код компилируется с учетом директив компиляции
То есть итоговый состав модуля зависит сразу от двух вещей:
- какой текст остался после препроцессора
- какие методы допускаются в данном контексте директивами компиляции
Пример 1
Заголовок раздела «Пример 1»Допустим, в модуле формы есть такой код:
&НаКлиентеПроцедура РаботаСФайлами()
#Если ВебКлиент Тогда // код для веб-клиента #Иначе // код для других клиентских приложений #КонецЕсли
КонецПроцедурыЧто здесь происходит:
- директива
&НаКлиентеозначает, что процедура может существовать в клиентском экземпляре модуля - инструкции препроцессора внутри процедуры определяют, какой именно текст останется для конкретного типа клиента
В результате:
- в веб-клиенте в модуле останется только ветка
#Если ВебКлиент Тогда - в других клиентских приложениях останется только ветка
#Иначе
📌 То есть сама процедура будет клиентской, но её содержимое может отличаться в зависимости от типа клиента.
Пример 2
Заголовок раздела «Пример 2»Теперь рассмотрим другую ситуацию:
#Если НаСервере Тогда&НаКлиентеПроцедура Клиентская()КонецПроцедуры#КонецЕслиЗдесь директива компиляции и инструкция препроцессора работают в разных направлениях.
Что получится:
- на сервере исходный текст процедуры после препроцессора останется
- но сама процедура не будет скомпилирована, потому что директива
&НаКлиентене допускает её существование на сервере - на клиенте процедура тоже не появится
- потому что клиентский вариант не пройдет через инструкцию
#Если НаСервере Тогда, и исходный текст будет исключен ещё до компиляции
📌 В итоге процедура не будет доступна ни на клиенте, ни на сервере.
Что показывают эти примеры
Заголовок раздела «Что показывают эти примеры»Эти примеры показывают главное:
- инструкции препроцессора определяют, какой текст вообще останется в модуле
- директивы компиляции определяют, какие методы и переменные попадут в конкретный экземпляр модуля
Поэтому при чтении кода в 1С важно смотреть сразу на оба уровня:
- что исключает препроцессор
- что допускает директива компиляции
Важный нюанс
Заголовок раздела «Важный нюанс»Методы, помеченные директивами:
&НаКлиентеНаСервере&НаКлиентеНаСервереБезКонтекста
могут попадать одновременно в разные экземпляры программного модуля.
Из-за этого один и тот же исходный метод может присутствовать сразу в нескольких контекстах, если это допускается типом модуля и директивой компиляции.
🧠 Ключевая мысль
Заголовок раздела «🧠 Ключевая мысль»1С работает в разных режимах и контекстах, и один и тот же исходный код может вести себя по-разному в зависимости от того, где и как он компилируется и выполняется.
Поэтому, чтобы писать корректные решения, разработчик должен понимать, в каком контексте будет существовать и работать его код.