将引用作为命名参数传递给可变参数函数时出现问题

发布于 2024-09-02 02:13:18 字数 649 浏览 6 评论 0原文

我在 Visual Studio 2003 中遇到以下问题:

void foo(const char*& str, ...) {
    va_list args;
    va_start(args, str);

    const char* foo;
    while((foo = va_arg(args, const char*)) != NULL) {
        printf("%s\n", foo);
    }
}

当我调用它时:

const char* one = "one";
foo(one, "two", "three", NULL);

我得到:

访问冲突读取位置0xcccccccc

printf() 行上的 - va_arg() 返回 0xcccccccc。我终于发现它的第一个参数是破坏它的引用——如果我将它设为普通的 char* 一切都很好。类型是什么似乎并不重要;作为引用会导致它在运行时失败。这是 VS2003 的已知问题,还是有某种合法行为?这在海湾合作委员会不会发生;我还没有使用较新的 Visual Studio 进行测试来查看该行为是否消失

I'm having problems in Visual Studio 2003 with the following:

void foo(const char*& str, ...) {
    va_list args;
    va_start(args, str);

    const char* foo;
    while((foo = va_arg(args, const char*)) != NULL) {
        printf("%s\n", foo);
    }
}

When I call it:

const char* one = "one";
foo(one, "two", "three", NULL);

I get:

Access violation reading location 0xcccccccc

on the printf() line -- va_arg() returned 0xcccccccc. I finally discovered it's the first parameter being a reference that breaks it -- if I make it a normal char* everything is fine. It doesn't seem to matter what the type is; being a reference causes it to fail at runtime. Is this a known problem with VS2003, or is there some way in which that's legal behavior? It doesn't happen in GCC; I haven't tested with newer Visual Studios to see if the behavior goes away

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

疾风者 2024-09-09 02:13:18

VS2005 也崩溃了。

问题是 va_start 使用给它的参数的地址,并且由于 str 是一个引用,因此它的地址是调用者定义的“one”变量的地址,而不是堆栈上的地址。

我看不出如何获取堆栈变量的地址(实际上包含正在传递的“one”的地址的参数),但有一些解决方法:

  • 使用“const char * &str”代替“const char * &str” "const char *str" 或 "const char **str"
  • 将下一个参数也添加到“固定”参数列表

此代码说明了第二种选择:

void foo(const char* &str, const char *arg1, ...) {
    if (arg1) {
       va_list args;
       va_start(args, arg1);
       printf ("%s\n", arg1);
       const char* foo;
       while((foo = va_arg(args, const char*)) != NULL) {
           printf("%s\n", foo);
       }
    }
}

VS2005 also crashes on it.

The problem is that va_start uses the address of the argument given to it, and since str is a reference, its address is the address of the "one" variable defined int the caller, not the address on the stack.

I see no way of getting the address of the stack-variable (the argument that actually contains the address of "one" that is being passed), but there are some work arounds:

  • Instead of "const char * &str", use "const char *str" or "const char **str"
  • Add the next argument also to the "fixed" argument list

This code illustrates the second alternative:

void foo(const char* &str, const char *arg1, ...) {
    if (arg1) {
       va_list args;
       va_start(args, arg1);
       printf ("%s\n", arg1);
       const char* foo;
       while((foo = va_arg(args, const char*)) != NULL) {
           printf("%s\n", foo);
       }
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文