c中不熟悉的函数声明

时间:2018-10-08 22:20:59

标签: c gcc

我正在研究SslSplit code。我在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 :(得分:3)

正如您指出的那样,NONNULLMALLOC只是 宏。它们的替换以__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。如果您检查 支持此扩展的编译器文档, 例如gccclang,您将找到完整的 说明。

GNU manual中的另一个属性malloc

  

这告诉编译器函数类似于malloc,即   该函数返回的指针P不能为其他任何指针加上别名   函数返回时有效,而且没有指向有效的指针   对象出现在P寻址的任何存储中。

     

使用此属性可以改善优化。像malloc这样的函数   和calloc具有此属性,因为它们返回一个指向   未初始化或清零的存储。但是,像realloc这样的函数   没有此属性,因为它们可以返回指向存储的指针   包含指针。