TIP: Click on subject to list as thread! ANSI
echo: aust_c_here
to: Frank Adam
from: david nugent
date: 1996-04-25 04:09:00
subject: Function args

DN>> enum { T_end =-1, T_int, T_ptr, T_long };
 DN>> void foo(int f,...)
 DN>> {
 DN>> int t;
 DN>> va_list arg;
 DN>> Not great code, but it should provide a starting point.

 FA> It's good, this is the best idea i've had so far :-)
 FA> But as i thought there is no way of not supplying a specifier for the
 FA> variables.

Umm, isn't that what it did?  :-)

You might have thought there was some magic available which might tell you
what was on the stack. And no, of course there isn't. The caller's stack
just bytes of data which the programmer provides a means to interpret. For
a function with fixed args, the parameters to a function and their type are
a contract between the caller and callee - and are bound statically by the
compiler and linker, at compile time. Variable length functions, however,
are a runtime concern, and the protocol used is the programmer's choice.

To simplify the previous example, you could use a "magic string"
of some sort, such as that used by *printf(). Or make it simpler again, and
say that as many args are passed as there are characters in the char array
pointed to by the first argument, that an 'i' character means an int, a 'd'
character means a double, a 's' means a char* and so on. So you'd be
looking at something like:

void foo(char const *fmt, ...)
{
  va_arg arp;
  va_start(argp,fmt);
  while (*fmt)
  {
    switch (*fmt++)
    {
    case 'i':
        {
            int i = va_arg(argp,int);
            /* ... */
        }
        break;
    case 's':
    /* and so on... */
    }
    
  }
  va_end(argp);
}

Anyway, the possibilities and permutations are endless. You invent the
contract on a "as needed" basis.

Actually, I've usually had very little need to create variable length
functions, and when I have it is almost always as an interface to
v?printf(), to take advantage of its formatting capabilities for special
I/O purposes.


 FA> Actually i never did look at pointer's sizes before,and i always thought
 FA> that the size of the pointer would be an indicator to the type.

Nope. In fact, C does not provide very much about the size of any
particular pointer at all, and the only requirement is that a void* be
large enough to hold a pointer to any type (to allow it to be cast back and
forth). In most implementations, a pointer to any object is the same size
as a pointer to any other object, but code that relies on that is not
"strictly conforming".

--- 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 506 544 639/252 711/401 409 410 413 430 808 809 932
SEEN-BY: 711/934 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™.