gpt4 book ai didi

c++ - 我可以引用 va_start() 吗?

转载 作者:行者123 更新时间:2023-11-30 00:46:05 27 4
gpt4 key购买 nike

为什么下面的代码不起作用?

#include <stdarg.h>
#include <stdio.h>

// People are missing this in their reponses.... 'fmt' here is passed by
// reference, not by value. So &fmt in _myprintf is the same as &fmt in
// myprintf2. So va_start should use the address of the fmt char * on the
// stack passed to the original call of myprintf2.
void _myprintf(const char *&fmt, ...)
{
char buf[2000];
//---
va_list ap;
va_start(ap, fmt);
vsnprintf(buf, sizeof(buf), fmt, ap);
va_end(ap);
//---
printf("_myprintf:%sn", buf);
}

void myprintf2(const char *fmt, ...)
{
_myprintf(fmt);
}

void myprintf(const char *fmt, ...)
{
char buf[2000];
//---
va_list ap;
va_start(ap, fmt);
vsnprintf(buf, sizeof(buf), fmt, ap);
va_end(ap);
//---
printf(" myprintf:%sn", buf);
}

int main()
{
const char *s = "string";
unsigned u = 11;
char c = 'c';
float f = 2.22;
myprintf("s='%s' u=%u c='%c' f=%fn", s, u, c, f);
myprintf2("s='%s' u=%u c='%c' f=%fn", s, u, c, f);
}

我希望两行输出相同,但它们不同:

 myprintf:s='string' u=11 c='c' f=2.220000
_myprintf:s='string' u=2020488703 c='c' f=0.000000

我以为va_start()用的是fmt变量的地址,应该是字符串指针在栈上的地址。

最佳答案

va_start 确实使用您提供给它的变量的地址。使用 myprintf2,您只将一个参数传递给 myprintf,因此当您尝试访问第二个参数(s 的传递值)时它不在那里,您会看到保存的寄存器、返回地址或位于堆栈中的其他内容。

要执行您想要执行的操作,您需要将 va_list 变量传递给由您的两个类似 printf 的函数调用的公共(public)函数。

编辑:根据 C++ 语言标准,“如果参数 parmN 是引用类型,或者是与传递没有参数的参数时产生的类型不兼容的类型,则行为未定义” (parmN是传递给va_start的参数。)

编辑 2:示例未编译实现:

void myprintf_core(const char *fmt, va_list ap);

void myprintf2(const char *fmt, ...) {
//...
va_list ap;
va_start(ap, fmt);
myprintf_core(fmt, ap);
va_end(ap); // could be included in myprintf_core
}

myprintf_core 是您的 _myprintf 但没有 3 个 va_ 行,它们已移至 myprintf2

关于c++ - 我可以引用 va_start() 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39732045/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com