Вы не можете легко написать макрос, который может отслеживать, что происходит со значением после его возврата, поскольку анализ потока данных несколько превосходит возможности препроцессора. Однако, есть полезный метод разработан, чтобы помочь в ситуациях, таких как это, что это определить функцию, которую вы хотите проверить, как самосправочные макро:
#define custom_get_value(...) (0, custom_get_value(__VA_ARGS__))
Этот пример ничего не делает сам по себе, но он демонстрирует что-то полезное: когда имя макроса появляется как часть своего собственного списка заметок, вложенное вхождение имени «окрашивается в синий цвет» и не будет расширяться во второй раз. Таким образом, определяя существующее имя функции как макроса, вы можете «обернуть» (или «посоветовать») все существующие вызовы функции, предположительно разбросанные по вашему коду в неизвестном количестве мест, - с дополнительными действиями, в дополнение к сохранению оригинальное обращение.
Тогда у вас есть несколько вариантов, например:
#define custom_get_value(...) ({ \
_Pragma("message \"custom_get_value called\""); \
custom_get_value(__VA_ARGS__); \
})
... если вы на GCC или Clang, следует перечислить файл и номер строки каждой точке, где custom_get_value
называется, во время компиляции , (Оба #pragma message
и форма выражения выражения являются нестандартными расширениями GCC, но если вы собираетесь использовать это при очистке старых вызовов, возможно, это не имеет значения? После того, как все вызовы отмечены, вы можете удалить нестандартный код.)
Или применить сообщение во время выполнения вместо:
#define custom_get_value(...) \
custom_wrap(custom_get_value(__VA_ARGS__), __FILE__, __LINE__)
void * custom_wrap(void * val, char * f, int l) {
printf("custom_get_value called in %s on line %d\n", f, l); return val;
}
... который отвезет вас орехи печати сообщения каждый раз, когда функция вызывается, но, по крайней мере стандарт.
Вы можете даже обернуть все вызовы функцией, которая гарантирует, что результирующий указатель гарантированно будет ненулевым, хотя это, вероятно, не лучший способ справиться с этой ситуацией.