объявление незнакомой функции в c - PullRequest
0 голосов
/ 09 октября 2018

Я искал SslSplit код .И я столкнулся с некоторыми незнакомыми, странными объявлениями функций в файле opts.h.Определение этих функций довольно простое, но я мог бы использовать некоторую помощь по объявлениям.Вот оно:

opts.h:

char *proxyspec_str(proxyspec_t *) NONNULL(1) MALLOC;
void opts_set_crl(opts_t *, const char *) NONNULL(1,2);

opts.c:

void
opts_set_crl(opts_t *opts, const char *optarg)
{
    if (opts->crlurl)
        free(opts->crlurl);
    opts->crlurl = strdup(optarg);
    log_dbg_printf("CRL: %s\n", opts->crlurl);
}

char *
proxyspec_str(proxyspec_t *spec)
{
    char *s;
    char *lhbuf, *lpbuf;
    char *cbuf = NULL;

    // Some code..

    return s;
}

attrib.h:

#define WUNRES          __attribute__((warn_unused_result))
#define MALLOC          __attribute__((malloc)) WUNRES
#define NONNULL(...)    __attribute__((nonnull(__VA_ARGS__)))

Мой вопрос такой: каковы значения NONNULL и MALLOC в конце объявлений функций?

1 Ответ

0 голосов
/ 09 октября 2018

Как вы сами отметили, NONNULL и MALLOC - это просто макросы.Их замена начинается с __attribute__, которое является ключевым словом расширения компилятора, используемым для определения атрибутов в функции.

__VA_ARGS__ является заменой переменного числа аргументов в макросе (объявлено с ...).Таким образом, это объявление:

void opts_set_crl(opts_t *, const char *) NONNULL(1,2);

преобразуется препроцессором (до того, как его увидит компилятор) в:

void opts_set_crl(opts_t *, const char *) __attribute__((nonnull(1,2)));

Что это эффективно делает, так это предотвращает появление первого и второго параметров NULL.Если вы посмотрите документацию компилятора, который поддерживает это расширение, например gcc или clang , вы найдете полное описание.

Другой атрибут, mallocиз руководства GNU :

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

Использование этого атрибута может улучшить оптимизацию.Такие функции, как malloc и calloc, имеют это свойство, поскольку они возвращают указатель на неинициализированное или обнуленное хранилище.Однако такие функции, как realloc, не имеют этого свойства, поскольку они могут возвращать указатель на хранилище, содержащее указатели.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...