【问题标题】:va_list and va_argva_list 和 va_arg
【发布时间】:2012-03-30 02:34:11
【问题描述】:

我像这样使用 va_list:

void foo(const char* firstArg, ...) {
    va_list args;
    va_start (args, firstArg);
    for (const char* arg = firstArg; arg != NULL; arg = va_arg(arg, const char*)) {
         // do something with arg
    }

    va_end(args);
}

foo("123", "234", "345")

前三个参数已正确传递给 foo,但在“345”完成的地方,

 arg = va_arg(arg, const char*) 

arg 设置一些其他的怪异值。

所以有什么问题。我使用 llvm3.0 作为编译器。

【问题讨论】:

  • 好的,我这样做foo("123", "234", "345", NULL)。我会测试它是否有效。
  • 你真的应该传递(char*)NULL,因为NULL 可能被定义为一个普通的0,编译器无法隐式知道它是一个没有强制转换的指针值。如果 sizeof(int) != sizeof(char *) 在 64 位实现中并不少见,这一点尤其重要。
  • 实际上不是这样。在 C11 中,§7.19 <stddef.h> 声明 宏是 NULL,它扩展为实现定义的空指针常量; 所以只有损坏的实现才能以不等效的方式定义 NULL到一个空指针。 §7.17 <stddef.h> 部分 C99 中的措辞是相同的,我相信 C89 也基本相同。
  • @JonathanLeffler 嗯,你提出了一个有趣的观点。我在回想c-faq.com/null/macro.html,这通常是相当可靠的(尽管有点迂腐),但在他们的回答中并不清楚它可能是一个普通的 0。
  • echo "#include <stddef.h>\nNULL" | gcc -E -x c - => ((void *)0)echo "#include <stddef.h>\nNULL" | gcc -E -x c++ - => __null。 Ubuntu 12.04 x86_64 上的 gcc 4.6.3。另见c-faq.com/null/safermacs.html

标签: c variadic-functions


【解决方案1】:

C 不会自动将NULL 放在... 参数列表的末尾。如果要使用NULL 来检测参数的结尾,则必须显式传递它。一些函数(例如printf)使用较早的参数来决定它们何时到达参数的末尾。

(编辑:实际上,如果您想在末尾添加NULL,您需要将其转换为适当的类型,以便将其作为正确类型的空指针传递。 )

【讨论】:

  • 您能否提供更多信息或链接,说明printf() 何时到达end of the argumentsprintf() 的工作方式是否与任何其他 function with a variable number of arguments 的工作方式完全相同?
  • 计算百分号的个数。
  • 我只是假设printf() 使用了两个va_list() 类型的指针。一个用于跟踪% 的论点和其他。对吗?
  • 你不需要 va_list 来计算字符串中的百分号。
【解决方案2】:

我觉得循环应该是这样的:

for (const char* arg = firstArg; arg != NULL; arg = va_arg(args, const char*))

更改为va_arg(args, const char*),而不是va_arg(arg/*<<==*/, const char*)

【讨论】:

    猜你喜欢
    • 2015-01-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-02
    • 2010-11-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多