Как создать обертки для библиотечных функций с оригинальным именем? - PullRequest
6 голосов
/ 15 октября 2019

Я нашел этот вопрос очень интересным: Как вызвать ошибку компиляции, если возвращаемое значение функции не проверено?

Речь идет о принудительном применении ошибок компиляции, если вы не проверяете возвращаемое значение. Я написал ответ на этот вопрос, где вы можете использовать расширения gcc следующим образом:

__attribute__ ((warn_unused_result)) int foo (void) 
{
    return 5;
}

для принудительного предупреждения и компиляции с -Werror=unused-result, чтобы компилятор выдавал ошибку, если вы не используетевернуть значение как-то.

Теперь я хотел бы создать функции-оболочки для обычных стандартных функций. Идея состоит в том, чтобы переименовать их так:

__attribute__ ((warn_unused_result)) realloc_wrapper(void *ptr, size_t new_size)
{
    return realloc(ptr, new_size);
}

Но проблема в том, что это заставляет меня использовать другое имя, что приведет к большому количеству поиска и замены. Конечно, это можно сделать автоматически, но все же. Предпочтительно, я хотел бы иметь возможность создавать заголовок, который я могу использовать вместо стандартного заголовка C для любой программы. Одним из вариантов использования является отладка большой программы. Тогда это немедленно укажет мне на потенциальные причины ошибок.

TL; DR

Короче говоря, я хочу иметь возможность взять эту программу:

#include <stdlib.h>

int main(void)
{
    char *ptr;
    realloc(ptr, 42);
}

и измените его на:

// Replaced stdlib with a custom header
#include <mystdlib.h>

int main(void)
{
    char *ptr;
    realloc(ptr, 42);
}

, а затем строка с realloc должна выдать предупреждение.

Могу добавить, что я в порядке с решением, которое не на 100% идеально. Предполагаемое использование для отладки, а не для производственного кода.

РЕДАКТИРОВАТЬ:

Я только что заметил, что realloc был плохой выбор, так как, кажется, это объявление уже есть по умолчанию, но я использовал PSkocik и заставил его работать для fgets.

1 Ответ

5 голосов
/ 15 октября 2019

Простым решением было бы замаскировать функцию макросом с одинаковым именем. (Я буду использовать puts в качестве примера, потому что, как вы упомянули, realloc обычно уже объявляется с warn_unused_result)

/*begin your header:*/

#include <stdio.h>

__attribute ((__warn_unused_result__)) static inline
int puts_wrapper(char const*X) 
{ 
   return (puts)(X); 
}
#define puts(X) puts_wrapper(X)

/*end your header*/

int main(void) { puts("hello, world"); }

(круглые скобки вокруг puts aren 'Это необходимо, но они позволяют вам переместить определение до определения puts_wrapper, если вы хотите.)

В качестве альтернативы, вы можете просто переопределить функцию с добавленным атрибутом warn_unused_result (работает как для gcc, так и для clang). ).

/*begin your header*/
#include <stdio.h>
__attribute ((__warn_unused_result__)) int puts(char const*);
/*end your header*/ 

int main(void) { puts("hello, world"); }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...