LINUX.ORG.RU

Выдавать ошибку при компиляции если используется «запрещенная» функция

 , , , ,


1

1

Всем привет, подскажите, как сделать так что бы компилятор выдавал ошибку если находил какую то функцию в списке «запрещенных»? и каким ключом сделать этот список?

то есть например, я хочу что бы если используют функцию strtok, то при компиляции выдавалась ошибка с каким то комментарием что нельзя ее использовать, а нужно использовать strtok_r. язык Си

#define strtok __restricted_function_use_strtok_r__
rupert ★★★★★ ()
Ответ на: комментарий от lignumq

ну попробуй тогда макросы добавить как rupert посоветовал.

fsb4000 ★★★★★ ()

В OpenBSD это решили например так: https://github.com/openbsd/src/blob/master/lib/libc/string/strcat.c

__warn_references(strcat,
    "strcat() is almost always misused, please use strlcat()");

Определение __warn_references см. тут: https://github.com/openbsd/src/search?q=__warn_references

Например для amd64:

#define __warn_references(sym,msg)					\
	__asm__(".section .gnu.warning." __STRING(sym)			\
	    " ; .ascii \"" msg "\" ; .text")
beastie ★★★★★ ()
Последнее исправление: beastie (всего исправлений: 1)
Ответ на: комментарий от beastie

А вот ещё интересно – более «новое» решение __warnattr: https://android.googlesource.com/platform/bionic/+/c13fb75%5E%21/

char* gets(char*) __warnattr("gets is very unsafe; consider using fgets");
int sprintf(char* __restrict, const char* __restrict, ...)
    __printflike(2, 3) __warnattr("sprintf is often misused; please use snprintf");
char* tmpnam(char*) __warnattr("tmpnam possibly used unsafely; consider using mkstemp");
int vsprintf(char* __restrict, const char* __restrict, __va_list)
    __printflike(2, 0) __warnattr("vsprintf is often misused; please use vsnprintf");

Сам __warnattr живёт в cdefs.h:

#if __GNUC_PREREQ (4,3)
# define __warndecl(name, msg) \
  extern void name (void) __attribute__((__warning__ (msg)))
# define __warnattr(msg) __attribute__((__warning__ (msg)))
# define __errordecl(name, msg) \
  extern void name (void) __attribute__((__error__ (msg)))
#else
# define __warndecl(name, msg) extern void name (void)
# define __warnattr(msg)
# define __errordecl(name, msg) extern void name (void)
#endif
beastie ★★★★★ ()
Последнее исправление: beastie (всего исправлений: 2)

Ещё есть #pragma GCC poison. Можно сложить такое в заголовок и подсунуть его через -include.

xaizek ★★★★★ ()

Если против привязки к clang ничего не имеете, то можно не просто выводить варнинг, а ище и автоматически заменять функцию, когда это возможно

https://llvm.org/docs/NewPassManager.html

Пишите pass, который это делает и его можно цеплять как внешний модуль к компилятору

SR_team ★★★★★ ()
Для того чтобы оставить комментарий войдите или зарегистрируйтесь.