繁体   English   中英

带指针的va_arg

[英]va_arg with pointers

我想用指针参数初始化一个链表,如下所示:

/* 
 * Initialize a linked list using variadic arguments
 * Returns the number of structures initialized
 */
int init_structures(struct structure *first, ...) 
{
    struct structure *s;
    unsigned int count = 0;
    va_list va;
    va_start(va, first);

    for (s = first; s != NULL; s = va_arg(va, (struct structure *))) {
        if ((s = malloc(sizeof(struct structure))) == NULL) {
            perror("malloc");
            exit(EXIT_FAILURE);
        }
        count++;
    }

    va_end(va);

    return count;
}

问题是clang错误type name requires a specifier or qualifier va_arg(va, (struct structure *)) type name requires a specifier or qualifier va_arg(va, (struct structure *)) ,并且说类型说明符默认为int。 它还注意到(struct structure *)struct structure *实例化形式。 这似乎是分配给sint (struct structure *)

当从(struct structure *)中删除括号时,它编译得很好,但是应该初始化的结构是不可访问的。

为什么在括号围绕传递给va_arg的类型参数时假设为int 我怎样才能解决这个问题?

va_arg是许多系统上的宏,显然围绕struct structure *的括号会导致宏扩展,因此无法解析。 所以不要这样做。

这与您的初始化结构“无法访问”的原因无关。 您正在分配结构并将它们分配给s ,但s是局部变量。 您不能通过分配局部变量来影响调用者中的值。 要完成你想要做的事情,调用者需要传递一个指向指针的指针,然后你可以初始化它

int init_structures(struct structure **first, ...) 
{
    struct structure **s;
    unsigned int count = 0;
    va_list va;
    va_start(va, first);

    for (s = first; s != NULL; s = va_arg(va, struct structure **)) {
        if ((*s = malloc(sizeof(struct structure))) == NULL) {
            perror("malloc");
            exit(EXIT_FAILURE);
        }
        count++;
    }

    va_end(va);

    return count;
}

调用者应该这样做:

struct structure *a, *b;
init_structures(&a, &b, NULL);

C99的 §7.15.1.1( va_arg宏)要求:

参数类型应该是一个特定的类型名称,这样只需通过将a *固定为类型就可以获得指向具有指定类型的对象的指针类型。

这就是为什么这里不允许使用括号的原因。

其他答案解释了为什么需要传入struct structure **并将malloc结果赋给*s

你不能在va_arg的类型周围放置parens。 你不需要。 va_arg是一个奇怪的野兽。 实际上,它是一个CPP宏,可以扩展到某种编译器时的魔力。 如果您使用编译器查看它的扩展,您将看到编译器如何执行它。 无论是什么,它都不喜欢parens。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM