On 10/03/2009, at 2:55 AM, Elvis Budimlic wrote:

What I went with in the rare cases where I did use them was the 'sentinel'
concept. One of my college professors liked it and it stuck with me.
Basically, you designate a special value (i.e. NULL) as the list terminator
(aka sentinel). Then the doStuff() function processes the list until it
hits the sentinel.

I've used that approach when passing in an array of pointers to stuff to process. The last element in the array is NULL and that acts as the sentinel. I'd have to rework the interface to make that work in this situation and it would be contrived and therefore unclean.

As far as I know, this is the issue with all C implementations, not just the
IBM i.

That was my guess too. The core of C implementations tends to be fairly standard.

For the relative 'safety' it provides, I actually like your #1 approach.
That's how main() works and for most C developers it wouldn't be a big leap
to understand the concept (i.e. for the consumers of your doStuff()

However with main() the "number of args" parameter is fairly transparent. Although the callee needs to check it the caller does not need to set it. It's done by the system.

I'd like something similar. I woke up this morning thinking perhaps Operational Descriptors could help. If I tell the compiler to supply an OpDesc for these functions it will set the number of parameters. The only issue is retrieving it. Sensible languages provide a means of determining the number of parameters received. C doesn't and the CEE APIs for OpDescs also don't give this value either. An oversight I would have thought since it is part of the information available in the descriptor structure. A CEEARGC API would be a useful thing to have.

There is an MI instruction NPM_PARMLIST_ADDR which is surfaced as built-in _NPMPARMLISTADDR which will give the caller access to the parameter list information. This method requires that an OpDesc is passed and will correctly provide the number of parameters passed by the caller.

My solution is to call _NPMPARMLISTADDR and extract the number of arguments then use this value to condition the va_arg macro calls to only extract values I **KNOW** are on the stack.

It's not a cross-platform solution but it's unlikely this code will ever run on other than XPF so I can live with it. If I do need to port it in the future a set of #ifdef blocks around this code will allow it to compile and the caller will be required to pass NULL or 0 for the optional parameters--making them required even though the prototype says otherwise. I could, if I chose, lie by providing a different #include for the consumer that replaced the ellipses with required parameters. The compiler would require the caller to pass something for those parameters and the underlying code could still use va_arg to address them. Win-win even if a bit obscure however the obscurity would only be with the maintainer of the underlying code (i.e., me) and not with the consumer. I can live with that.

Code inside doStuff() looks like:

va_list ap;
_NPM_ParmListAddr_T * plist = NULL;
_NPM_DescList_T * dlist = NULL;
int p2 = 0;
char * p3 = NULL;
double p4 = 0.0;

dlist = plist->dlist;
nbrArgs = dlist->argc;

va_start( ap, p1 );
if ( nbrArgs >= 2 )
p2 = va_arg( ap, int );
if ( nbrArgs >= 3 )
p3 = va_arg( ap, char * );
if ( nbrArgs >= 4 )
p4 = va_arg( ap, double );
va_end( ap );

Now all I need to do is determine how to define an OpDesc for a function pointer. Compiler barfs but I think I can work around that.

Simon Coulter.
FlyByNight Software OS/400, i5/OS Technical Specialists

Phone: +61 2 6657 8251 Mobile: +61 0411 091 400 /"\
Fax: +61 2 6657 8251 \ /
ASCII Ribbon campaign against HTML E-Mail / \

This thread ...


Follow On AppleNews
Return to Archive home page | Return to MIDRANGE.COM home page

This mailing list archive is Copyright 1997-2019 by midrange.com and David Gibbs as a compilation work. Use of the archive is restricted to research of a business or technical nature. Any other uses are prohibited. Full details are available on our policy page. If you have questions about this, please contact [javascript protected email address].