Как определить макрос с несколькими прагмами для Clang? - программирование
Подтвердить что ты не робот

Как определить макрос с несколькими прагмами для Clang?

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

Я хотел бы включить это:

#pragma clang diagnostic push
#pragma clang diagnostic warning "-Wdeprecated-declarations"

void Foo() __attribute__((deprecated("Warning: deprecated routine")))

#pragma clang diagnostic pop

в это:

MY_DEPRECATED_BEGIN

void Foo() MY_DEPRECATED

MY_DEPRECATED_END

Макрос MY_DEPRECATED_BEGIN дает мне проблемы, поскольку я должен указать две прагмы в одном макросе. Это можно сделать?

(Бонусные точки для решения, которое достигает того же эффекта, используя только макрос MY_DEPRECATED!)

4b9b3361

Ответ 1

void Foo() __attribute__((deprecated));

#define MY_DEPRECATED_BEGIN \
    _Pragma("clang diagnostic push") \
    _Pragma("clang diagnostic warning \"-Wdeprecated-declarations\"")


int main()
{
MY_DEPRECATED_BEGIN
    Foo();
#pragma clang diagnostic pop
}

Короткий ответ на ваш технический вопрос заключается в том, что C99 предоставляет конструкцию _Pragma("foo"), которая эквивалентна #pragma foo, но обрабатывается чуть позже и не обязательно должна быть в отдельной строке.

Другая проблема заключается в том, что -Wdeprecated-declarations не делает то, что, по вашему мнению, делает. Просто объявление функции как устаревшей никогда не даст вам диагностики, потому что предполагается, что __attribute__((deprecated)) используется (как правило, в заголовочных файлах). Что вызывает диагностику, если вы используете устаревшую функцию - и в этот момент становится актуальной установка -Wdeprecated.

Если вы действительно хотите отказаться от Foo iff MY_DEPRECATED, тогда правильный способ сделать это

#ifdef MY_DEPRECATED
 #define ATTRIBUTE_DEPRECATED __attribute__((deprecated))
#else
 #define ATTRIBUTE_DEPRECATED
#endif

void Foo() ATTRIBUTE_DEPRECATED;

Ответ 2

Вы можете использовать это решение:

#define NS_SUPPRESS_DIRECT_USE(expr)   _Pragma("clang diagnostic push") \
                                       _Pragma("clang diagnostic ignored \"-Wdeprecated-declarations\"")\
                                       expr\
                                       _Pragma("clang diagnostic pop") 

Затем просто добавьте его:

NS_SUPPRESS_DIRECT_USE(
                      Foo();
                      );