Как использовать макрос препроцессора во включении?

Я пытаюсь построить freetype2 используя мою собственную систему сборки (я не хочу использовать Jam, и я готов потратить время на выяснение этого). Я нашел что-то странное в заголовках. Freetype определяет макросы следующим образом:

#define FT_CID_H  <freetype/ftcid.h>

а затем использует их позже, как это:

#include FT_CID_H

Я не думал, что это возможно, и действительно Clang 3.9.1 жалуется:

error: expected "FILENAME" or <FILENAME>
#include FT_CID_H
  • В чем причина этих макросов?
  • Это действительный C / C ++?
  • Как я могу убедить Clang разобрать эти заголовки?

Это связано с Как использовать макрос в директиве #include? но отличается, потому что здесь речь идет о компиляции freetype, а не о написании нового кода.

9

Решение

Это действительный C / C ++?

Использование действительно C, при условии, что определение макроса находится в области действия в точке, где #include директива появляется. В частности, пункт 6.10.2 / 4 С11 говорит

Директива предварительной обработки вида

# include pp-tokens new-line

(что не соответствует одной из двух предыдущих форм) разрешено.
токены предварительной обработки после включения в директиву обрабатываются просто
как в обычном тексте. (Каждый идентификатор в настоящее время определен как имя макроса
заменяется списком замен токенов предварительной обработки.
)
директива, возникающая после всех замен, должна соответствовать одной из двух
предыдущие формы.

(Акцент добавлен.) Поскольку препроцессор имеет ту же семантику в C ++, что и в C, насколько мне известно, использование также допустимо в C ++.

В чем причина этих макросов?

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

Как я могу убедить Clang разобрать эти заголовки?

При условии, опять же, что определение макроса находится в области действия в точке, где #include появляется директива, вам не нужно ничего делать. Если это действительно так, то Clang глючит в этом отношении. В этом случае, после подачи отчета об ошибке (если эта проблема еще не известна), вам, вероятно, придется расширить проблемные ссылки на макросы вручную.

Но прежде чем сделать это, убедитесь, что определения макросов действительно находятся в области видимости. В частности, они могут быть защищены директивами условной компиляции — в этом случае наилучшим способом действий, вероятно, было бы обеспечение любого макроопределения, необходимого (через командную строку компилятора) для удовлетворения условия. Если от вас ожидают, что это будет сделано вручную, то, несомненно, в документации по сборке это обсуждается. Прочитайте инструкцию по сборке.

6

Другие решения

Я отвечу на ваши три вопроса не по порядку.

вопрос 2

Это действительный C / C ++?

Да, это действительно так. Расширение макроса может быть использовано для создания окончательной версии #include директивы. Цитата C ++ 14 (N4140) [cpp.include] 16.2 / 4:

Директива предварительной обработки вида

# include pp-tokens new-line

(что не соответствует одной из двух предыдущих форм) разрешено. Токены предварительной обработки после include
в директиве обрабатываются так же, как и в обычном тексте (т.е. каждый идентификатор, определенный в настоящее время как имя макроса,
заменен его списком замен токенов предварительной обработки). Если директива, получающаяся после всех замен,
не соответствует ни одной из двух предыдущих форм, поведение не определено.

Упомянутые «предыдущие формы» #include "..." а также #include <...>, Так что да, допустимо использовать макрос, который расширяется до заголовка / файла для включения.

Вопрос 1

В чем причина этих макросов?

Понятия не имею, так как никогда не использовал библиотеку freetype2. На этот вопрос лучше всего отвечают его каналы поддержки или сообщество.

Вопрос 3

Как я могу убедить Clang разобрать эти заголовки?

Поскольку это законный C ++, вам не нужно ничего делать. Действительно, пользователь @Fanael имеет продемонстрировал что Clang способен анализировать такой код. В вашей настройке должна быть какая-то проблема, другая проблема или что-то еще, чего вы не показывали.

11

По вопросам рекламы [email protected]