I'm trying to convert some very old C on AIX7.3 to use stdarg instead of varargs. The code was originally compiled with XLC, but I'm being forced to use gcc now. I'm trying to avoid the need to change the calling programs as this could get very painful. I have a simple example here: -
msclear_str( va_alist )
va_dcl
{
STRING *str;
va_list ap;
va_start(ap);
while ( (str = va_arg(ap, STRING *)) != (STRING *)0)
{
if ( str->id == '\001' )
{
_dispose( str );
}
else
{
mssinit( str );
}
}
va_end(ap);
}
and I've attempted to convert it and have ended up with this: -
msclear_str(STRING *STR, ... )
{
STRING *str;
va_list ap;
va_start(ap, STR);
str = STR;
while ( (str) != (STRING *)0)
{
if ( str->id == '\001' )
{
_dispose( str );
}
else
{
mssinit( str );
}
}
va_end(ap);
}
I haven't used C for a very long time and wondered if anyone could advise on whether want I've done makes sense and would work in the same way. The need for a fixed parameter is what is really getting be confused. I have more complex examples with multiple parameters that actually seem simpler in this regard - daft I know.
I'm trying to convert some very old C on AIX7.3 to use stdarg instead of varargs. The code was originally compiled with XLC, but I'm being forced to use gcc now. I'm trying to avoid the need to change the calling programs as this could get very painful. I have a simple example here: -
msclear_str( va_alist )
va_dcl
{
STRING *str;
va_list ap;
va_start(ap);
while ( (str = va_arg(ap, STRING *)) != (STRING *)0)
{
if ( str->id == '\001' )
{
_dispose( str );
}
else
{
mssinit( str );
}
}
va_end(ap);
}
and I've attempted to convert it and have ended up with this: -
msclear_str(STRING *STR, ... )
{
STRING *str;
va_list ap;
va_start(ap, STR);
str = STR;
while ( (str) != (STRING *)0)
{
if ( str->id == '\001' )
{
_dispose( str );
}
else
{
mssinit( str );
}
}
va_end(ap);
}
I haven't used C for a very long time and wondered if anyone could advise on whether want I've done makes sense and would work in the same way. The need for a fixed parameter is what is really getting be confused. I have more complex examples with multiple parameters that actually seem simpler in this regard - daft I know.
Just the first one has to be an arg. Looks nice with a for loop.
void msclear_str(STRING *STR, ... ) {
va_list ap;
va_start(ap, STR);
for (STRING *str = STR; str != NULL; str = va_arg(ap, STRING *))
{
if ( str->id == '\001' )
{
_dispose( str );
}
else
{
mssinit( str );
}
}
va_end(ap);
}
If I understand correctly, the last argument has to be 0
. With gcc you might also be interested in __attribute__ ((sentinel))
to get a warning, see https://gcc.gnu./onlinedocs/gcc/Common-Function-Attributes.html#index-sentinel-function-attribute .
STRING *STR
should only be in the parameter list, not as a separate statement. – Barmar Commented Mar 4 at 18:12va_arg()
. How do you expect to access the remaining arguments? – Barmar Commented Mar 4 at 18:19