В целях отладки я пытаюсь вывести информацию о том, определены ли определенные символы, но без необходимости ухудшать читаемость кода слишком большим количеством блоков #if defined()
. Я попробовал использовать оператор defined()
при выводе текста с помощью #pragma message
вот так:
#pragma message defined(__UNDERLAY__)
Я ожидал, что на выходе будет 1, если __UNDERLAY__
определен, и 0, если нет. Но вместо этого:
testbed_defines.c:61:9: warning: expected a string after ‘#pragma message’ [-Wpragmas]
61 | #pragma message defined(__UNDERLAY__)
| ^~~~~~~
Я попытался "строчить" вот так:
#pragma message "" defined(__UNDERLAY__)
Это вызвало только другую ошибку:
testbed_defines.c:61:9: warning: junk at end of ‘#pragma message’ [-Wpragmas]
61 | #pragma message "" defined(__UNDERLAY__)
| ^~~~~~~
Я попробовал оператор конкатенации:
testbed_defines.c:61:20: error: stray ‘##’ in program
61 | #pragma message "" ## defined(__UNDERLAY__)
| ^~
testbed_defines.c:61:9: warning: junk at end of ‘#pragma message’ [-Wpragmas]
61 | #pragma message "" ## defined(__UNDERLAY__)
| ^~~~~~~
Есть ли способ вывести значение defined(x)
без необходимости создания блока #if
? Тем более, что для этого мне нужно будет записать два допустимых значения (0 и 1) в код, как магические числа. Похоже, defined
здесь вообще не оценивается!
Pragma во многом зависит от компилятора. Некоторые компиляторы расширяют сообщения, некоторые нет. Разные компиляторы делают это по-разному. Какой компилятор вы используете?
@pts Когда таких блоков для проверки много, большое количество блоков #ifdef ... #endif
ухудшит читаемость кода. И, как я уже упоминал, мне бы хотелось избежать жесткого кодирования допустимых выходных значений define()
как магических чисел.
@KamilCuk Хорошая мысль. Я использую gcc и только что добавил тег [gcc]
для пояснения.
«Есть ли способ вывести значение define(x) без необходимости создания блока #if?» Нет.
@n.m.couldbeanAI Раздел 6.10.1 проекта C11 (N1570) описывает defined()
, но ничего не говорит о том, что он должен находиться в блоке #if
. Можете ли вы привести источник, подтверждающий ваше утверждение?
Вы можете использовать любой идентификатор где угодно. Это просто не будет иметь того же значения, что и в блоке #if. Раздел, на который вы ссылаетесь, описывает значение defined
, используемого в блоке #if. За пределами одного это просто обычный идентификатор.
Есть ли способ вывести значение define(x) без необходимости создания блока #if?
Нет. defined()
оценивается только внутри #if
, #elif
и тому подобного.
Вы можете проверить, расширяется ли макрос до нуля, с помощью https://gustedt.wordpress.com/2010/06/08/detect-empty-macro-arguments/ .
Невозможно расширить до 1 или 0 в зависимости от того, определен ли макрос Есть ли способ преобразовать переменный макрос в 0 или 1 в зависимости от того, определен ли он? .
У вас есть источник для этого? Раздел 6.10.1 проекта C11 (N1570) описывает defined()
, но ничего не говорит о #if
или #ifelse
.
@AJM: Если вы видели defined
, описанный в C 2011 6.10.1, вы видели заголовок этого пункта: «Условное включение». В этом пункте описывается исключительно функция условного включения предварительной обработки, то есть директивы #if
, #ifdef
, #ifndef
, #elif
, #else
и #endif
. Предложение, описывающее defined
, начинается со слов «Выражение, управляющее условным включением, должно быть…», и именно в этом контексте описывается defined
. Это происходит исключительно в контексте выражения, управляющего условным включением.
@AJM: По поводу «… 6.10.1 … но ничего не говорится о #if
или #ifelse
»: Это странно. Во-первых, это #elif
, а не #ifelse
. Во-вторых, 6.10.1 содержит шесть параграфов. Упоминания #if
встречаются в абзацах 3, 4 и 5.
@EricPostpischil Чтобы уточнить, в пункте 1 раздела 6.10.1 описывается defined()
, но не упоминаются #if
или #ifelse
. Остальные абзацы не описывают defined
. Я бы вернулся и отредактировал этот комментарий с этим пояснением, но сейчас у меня истек 5-минутный лимит.
Снова подумав о абзацах 3 и 5 в свете вашего комментария... действительно начинает казаться, что я не могу этого сделать и мне придется принять этот ответ и двигаться дальше.
@EricPostpischil Кроме того, я упомянул #ifelse
, потому что об этом упоминалось в ответе. Я этого не узнал, но, по крайней мере, смог сказать, что в этой части C11 об этом не упоминалось.
Извините, ничего умного вы не можете сделать. Лучшее, что вы можете сделать, это
#ifdef __UNDERLAY_\
#pragma message “__UNDERLAY is defined”
#else
#pragma message “__UNDERLAY__ is not defined”
#endif
Вы не можете, например, превратить это в макрос. Вы можете добиться большего, если у вас есть макрос, который гарантированно будет либо неопределенным, либо определенным с ненулевым целочисленным значением.
Почему бы не поставить
#pragma
внутри#ifdef
?