Как отказаться от макроса в GCC? - PullRequest
13 голосов
/ 21 апреля 2010

я знаю, как использовать атрибут устарел для устаревания функции, подобной этой:

int old_fn () __attribute__ ((deprecated));

Но как отменить макрос, как это:

#define OLD_MACRO 1

Заранее спасибо.

Eric

Ответы [ 4 ]

12 голосов
/ 27 марта 2015

Хорошее, элегантное решение, однако, в зависимости от того, включен ли C99 (работает с gcc 4.8.2 или новее, не тестировался в более ранних версиях):

#define DEPRECATED_MACRO1 _Pragma ("GCC warning \"'DEPRECATED_MACRO1' macro is deprecated\"") 7
#define DEPRECATED_MACRO2(...) _Pragma ("GCC warning \"'DEPRECATED_MACRO2' macro is deprecated\"") printf(__VA_ARGS__)

int main(int argc, char*argv[])
{
    int n = DEPRECATED_MACRO1;
    DEPRECATED_MACRO2("%d\n", n);
    return 0;
}
8 голосов
/ 21 апреля 2010

Я думаю, что лучшее, что вы можете сделать, это что-то вроде этого:

#ifdef USE_DEPRECATED_MACROS
#warning using deprecated macros
#define OLD_MACRO 1
...
#endif

Таким образом, вы заставляете пользователя, например, добавьте -DUSE_DEPRECATED_MACROS к параметрам компилятора, и они получат предупреждение.

5 голосов
/ 21 апреля 2010

Вы можете убедиться, что эти макросы будут расширены до чего-то, что будет включать выражение, которое вызовет предупреждение attribute ((устарело)).

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

#define DEPRECATE(name) static inline void __attribute__((deprecated)) deprecate_ ## name (void) { ; }
...
#define MAX(x, y) (DEPRECATE(MAX), x>y?x:y)
// yeah, yeah, it repeats args in the body, but it's just an example

Для определения константы вы, вероятно, захотите предположить, что тело должно вычислять без необходимости генерировать код, например, вне тела функции, в целях переключателя / регистра или в качестве начального значения статической переменной. внутри функции.

Это сложно, но вы можете сделать это для многих вещей.

Мне бы хотелось, чтобы C имел __builtin_warn (const char *), который работал бы на уровне компилятора (не препроцессора) и облегчал бы такие вещи.

редактировать

Для константных определений вы можете сделать:

#define THREE (DEPRICATED(THREE),3)
1 голос
/ 21 апреля 2010

Поскольку макросы не являются частью компилятора (они являются функцией препроцессора), чистого способа сделать это не существует. В лучшем случае поместите устаревшие макросы в новый заголовочный файл, заполненный #warnings. Это, конечно, сломает существующий код, но это один из способов гарантировать привлечение внимания к устареванию.

...