Как реализовать макрос, который создает строку в кавычках для _Pragma?

Я хочу иметь макрос, который вызывается следующим образом:

GCC_WARNING(-Wuninitialized)

который расширяется до такого кода:

_Pragma("GCC diagnostic ignored \"-Wuninitialized\"")

Мне не повезло заставить это работать, так как обычные приемы препроцессорных соединений и строк, похоже, не применяются, или я не знаю, как их применить здесь.


person ThreeBit    schedule 04.01.2012    source источник


Ответы (2)


С небольшой помощью магии препроцессора:

#define HELPER0(x) #x
#define HELPER1(x) HELPER0(GCC diagnostic ignored x)
#define HELPER2(y) HELPER1(#y)
#define GCC_WARNING(x) _Pragma(HELPER2(x))

GCC_WARNING(-Wuninitialized)
person Lindydancer    schedule 04.01.2012
comment
Спасибо, но это не работает, вероятно, из-за того, что он не ставит \ вокруг -Wuninitialized. Приведенное выше использование макроса приводит к следующей ошибке GCC: игнорирование диагностики #pragma GCC [-Wunknown-pragmas] - person ThreeBit; 06.01.2012
comment
Он заключает в кавычки -Wuninitialized. Проблема заключалась в опечатке diagnostics вместо diagnostic — я исправил ее в ответе выше. - person Lindydancer; 06.01.2012

Было бы также приемлемо, если бы аргумент макроса был заключен в одинарные кавычки? Если это так, вы можете использовать это:

#define GCC_WARNING(x) _Pragma("GCC diagnostic ignored '" #x "'")

При вызове его как GCC_WARNING(-Wuninitialized) он расширяется до

_Pragma("GCC diagnostic ignored '" "-Wuninitialized" "'")

Мне пришлось использовать поведение конкатенации строк C (printf("a" "b"); такое же, как printf("ab");) здесь, поскольку использование "'#x'" в макросе позволит избежать расширения x.

person Frerich Raabe    schedule 04.01.2012
comment
Почти... на самом деле _Pragma имеет особое значение для gcc. Я публиковал аналогичное решение, но понял, что оно не работает с моим gcc, потому что препроцессор жалуется (ошибка: _Pragma принимает строковый литерал в скобках). - person Giuseppe Guerrini; 04.01.2012
comment
Это не сработает — _Pragma интерпретирует свой аргумент до объединения строк, поэтому он увидит две строки, а не одну. В отличие от printf, это особая конструкция, подчиняющаяся особым правилам. - person Lindydancer; 04.01.2012
comment
Ах, как глупо, мне не приходило в голову, что это был вопрос, специфичный для GCC. Я думал, что _Pragma это какая-то пользовательская функция отладки, но теперь, когда я смотрю на имя макроса, я должен был знать лучше. - person Frerich Raabe; 04.01.2012
comment
На самом деле _Pragma не относится к GCC. Это часть стандарта C99, позволяющая макросам расширяться до прагмы. Тем не менее, пользователь спросил о конкретном случае использования GCC, но вопрос по-прежнему будет актуален и для общих прагм. - person Lindydancer; 04.01.2012
comment
@Lindydancer: Интересно! Я даже не знал, что это часть стандарта C99. Сегодня узнал кое-что новое. :-) - person Frerich Raabe; 04.01.2012