views:

158

answers:

5

Purely for interest, I am re-learning C after ... I don't know ... 15 - 20 years.

I seem to recall that variable arguments were implemented as simple macros.

  • Can anyone remember what they were?

Edit: To clarify my question, I know they had the same name as va_list etc. but can you remember the actual macro definition?

  • Will they still work today?
+4  A: 

You're thinking of va_list, va_arg, va_start, and va_end from stdarg.h (link to WP article). They still work just fine. :-)

T.J. Crowder
Yes, Thanks. I edited my question since I was interested in the actual macro definition. today GCC has them as __builtin__...
philcolbourn
@Philcolbourn: I don't think I ever knew, I just used them. But searching on "define va_start" found me a couple of sources, here's the top result (very slow but does come up eventually): http://research.microsoft.com/en-us/um/redmond/projects/invisible/include/stdarg.h.htm
T.J. Crowder
@ T.J Crowder: Thanks. I found this too, but they look a lot more complicated than I remember - perhaps I remember wrongly.
philcolbourn
@phil: Everything seems easier to the young. ;-) *(Disclosure: Let's just say I was using these before the C89 standard and leave it at that...)*
T.J. Crowder
+1  A: 

Variadic functions are indeed commonly implemented using macros. These are standardised - see this wikipedia article on the subject. The actual macro definitions are dependent on the processor architecture, as they have to play non-portable games with the call stack.

anon
Thanks Neil. StackOverflow answers are like a race-condition.
philcolbourn
A: 

Variable arguments today are done via the interface described in <stdarg.h> - as to how they were done 15 years ago, I really can't say.

gnud
Basically the same way `alignof` is done today, with clever user defined macros that (should) make it into the next standard.
Tim Post
*"as to how they were done 15 years ago, I really can't say"* The same way -- more than 15 years ago, we're talking the early 80s at least and possibly even the 70s. They were standardized in C89 (the ANSI standard in 1989), but in use *well* before that.
T.J. Crowder
A: 

Its hard to say if your implementation of them from way back when would still work, however they are pretty much the same as others have pointed out, they just moved into a standard header (standard being the operative word).

What a compiler expands as a built in is up to the compiler, and the flags that you pass to it when invoking it.

Keep in mind that gcc is not the only C compiler, but it (like others) conforms to c89 and c99.

Tim Post
+1  A: 

Even before the standardisation, methods of doing variable arguments were common. The C89 standard gave a ... standardized interface based on the existing practices. Remainders of those practice still exist at place, for instance <varargs.h> was still present in Unix98: http://www.opengroup.org/onlinepubs/007908799/xsh/varargs.h.html (but is no more present in current version)

The implementation of the macros was always very much system dependent (there are stacks growing in both directions, there are even systems using a linked list as stack, position of various things in the stack frame depend on the processor and common convention, on some processors -- says Sparc -- one need first to save the registers, alignment requirements may cause problems,...)

If you want to know what would a simple implementation looks like, here is one, depending on assumptions probably false (they don't try to get any alignment right) and also certainly failing some corner cases even when the assumptions hold:

typedef void* va_list;
#define va_start(va, arg) va = (void*)((&arg)+1)
#define va_arg(va, type)  (va = (void*)(((type*)va) + 1), *((type*)va -1)
#define va_end(va)
AProgrammer
philcolbourn
Ellipse is an invention of C89 and its introduction allows vararg functions to have a different ABI than normal one. In your implementation, _INTSIZEOF is there to ensure a stricter alignment (useful for types like char and short).
AProgrammer