TIP: Click on subject to list as thread! ANSI
echo: aust_c_here
to: Frank Adam
from: david nugent
date: 1996-04-22 02:42:48
subject: Function args

FA> Is it at all possible to send  variable type and number of args to a
 FA> function, and determine the types and number of them at runtime ?

Sure, even if it means passing an arg with a counter, putting a NULL or
some other magic value at the end - whatever method you want to use to do
it, you can.

 FA> eg. void foo(char*,...);

 FA> foo("hello",10,5.6,'o');
 FA> foo(10.7,90,"Hello",'i',90,80);

 FA> This may not make any sense, but i'm curious if there
 FA> is a way of doing it.

#include 

void foo(char * fmt,...)
{
    va_list arg;

    va_start(arg, fmt);
    // .. your code, you can use va_arg(arg,) to retrieve
    // the next arg from the stack of type 
    va_end(arg);
}


 FA> If there is, how would i then check for the type ?

You have to work out a method of doing that yourself.

With the printf() family, the type is embedded into the %?'s included in
the format string.  An alternative might be to define an enumerator, and
preceed each arg with a description of its type, for example:

/* Warning: untested, unchecked code follows :-) */

#include 
#include 

enum { T_end =-1, T_int, T_ptr, T_long };

void foo(int f,...)
{
    int t;
    va_list arg;

    va_start(arg, f);
    for (t = f; t != T_end; t = va_arg(arg,int))
    {
        switch (t)
        {
            case T_int:
                {
                    int d = va_arg(arg,int);
                    printf("arg was the integer %d\n", d);
                }
                break;
            case T_long:
                {
                    long l = va_arg(arg,long);
                    printf("arg was the long %ld\n", l);
                }
                break;
            case T_ptr:
                {
                    void * p = va_arg(arg,void *);
                    printf("arg was the pointer %p\n", p);
                }
                break;
        }
    }
    va_end(arg);
}

int main()
{
    foo(T_int, 5, T_long, 3984756L, T_ptr, main, T_end);
    foo(T_long, 983985L, T_ptr, (void*)NULL, T_end);
    return 0;
}

(note the cast on NULL is just a precaution and not necessary - except, of
course, for portability - if either your compiler #define's NULL to be
(void*)0, or #define'd as 0 and sizeof(int)==sizeof(void*)).

Not great code, but it should provide a starting point.

--- MaltEd/2 1.0.b6
* Origin: Unique Computing Pty Limited (3:632/348)
SEEN-BY: 50/99 78/0 620/243 623/630 632/103 348 360 998 633/371 634/388 396
SEEN-BY: 635/301 502 503 544 639/252 711/401 409 410 413 430 808 809 932 934
SEEN-BY: 712/515 713/888 714/906 800/1 7877/2809
@PATH: 632/348 635/503 50/99 711/808 809 934

SOURCE: echomail via fidonet.ozzmosis.com

Email questions or comments to sysop@ipingthereforeiam.com
All parts of this website painstakingly hand-crafted in the U.S.A.!
IPTIA BBS/MUD/Terminal/Game Server List, © 2025 IPTIA Consulting™.