Reputation: 648
Ok, so this piece of code works fine in the Debug but not in Release build.
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 ...
}
It seems in Release, va_arg just returns an extra value containing rubbish. So if I pass on 3 parameters: I fetch 3 in Debug and miraculously 4 in Release... How is this possible? Using VS2010 btw.
(RArray is just a simple template class comparable to MFC's CArray, does not influence results)
Thanks!
Edit: I call it like this
AddString(_T("Hello, world!"), _T("Hallo, wereld!"), _T("Hallo, Welt!"));
Upvotes: 2
Views: 195
Reputation: 145279
va_arg
does not offer any guarantee to return 0 after last real argument.
If you're going to use the C style variable arguments, then you need to establish some way of determining the number of arguments, e.g. a count or a terminating zero.
For example, printf
determines the arguments from the format specification argument.
In C++ you can often, instead, use chained calls, such as the operator<<
calls used for standard iostreams.
The simple, basic idea is that the operator or function returns a reference to the object that it is called on, so that further operator or function calls can be appended.
Cheers,
Upvotes: 0
Reputation: 96266
You're doing it the wrong way and you're just lucky with the debug build.
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.
Supply either the length of the list in an integer or pass a NULL at the end of the list.
Upvotes: 2
Reputation: 500367
You're not supplying the final NULL
argument your function expects. You have to do this yourself at the point where you call AddString
:
AddString(_T("Hello, world!"), _T("Hallo, wereld!"), _T("Hallo, Welt!"), NULL);
It is likely that the debug build zeros out some memory that the release build doesn't. This could explain why your code works in debug but not in release.
Also, you might want to convert the do {} while (...)
loop into while (...) {}
, to make sure your code doesn't malfunction if no optional arguments are given.
Upvotes: 0