变量论证古怪

时间:2011-08-01 09:07:03

标签: c++

好的,所以这段代码在Debug中运行良好,但在Release版本中没有。

int AddString(LPCTSTR lpszString, ...)
{
    RArray<LPCTSTR> strings;
    va_list args;
    va_start(args, lpszString);
    do
    {
        strings.Add(lpszString); 
    } while (lpszString = va_arg(args, LPCTSTR));
    va_end(args);

    // ... rest of code ...
}

似乎在Release中,va_arg只返回一个包含垃圾的额外值。所以,如果我传递3个参数:我在Debug中获取3,奇迹般地在Release 4中获取4 ...这怎么可能?使用VS2010 btw。

(RArray只是一个与MFC的CArray相当的简单模板类,不影响结果)

谢谢!

编辑:我称之为

AddString(_T("Hello, world!"), _T("Hallo, wereld!"), _T("Hallo, Welt!"));

3 个答案:

答案 0 :(得分:2)

你这样做的方式是错误的,你只是对调试版本很幸运。

Notice that va_arg does not determine either whether the retrieved argument
is the last argument passed to the function (or even if it is an element
past the end of that list). The function should be designed in such a way
that the amount of parameters can be inferred in some way by the values of
either the named parameters or the additional arguments already read.

以整数形式提供列表长度或在列表末尾传递NULL。

答案 1 :(得分:0)

您没有提供函数期望的最终NULL参数。您必须在致电AddString时自行执行此操作:

AddString(_T("Hello, world!"), _T("Hallo, wereld!"), _T("Hallo, Welt!"), NULL);

调试版本可能会将发布版本没有的内存清零。这可以解释为什么你的代码在调试中工作但不在发布中。

此外,您可能希望将do {} while (...)循环转换为while (...) {},以确保在没有给出可选参数的情况下代码不会出现故障。

答案 2 :(得分:0)

va_arg不保证在最后一次真实参数后返回0。

如果您要使用C样式变量参数,那么您需要建立一些确定参数数量的方法,例如:计数或终止零。

例如,printf确定格式规范参数的参数。

在C ++中,您通常可以使用链式调用,例如用于标准iostream的operator<<调用。

简单,基本的想法是操作符或函数返回对其被调用的对象的引用,以便可以追加进一步的操作符或函数调用。

干杯,