Greetings!
I'm trying to replace cstdargs and I got a working implementation after researching online and reading different book snippets. Here's what I have:
[Code]
typedef char *Va_list;
#define ALIGNMENT 8
#define BOUNDARY(X)\
((sizeof(X) + (ALIGNMENT - 1)) & ~(ALIGNMENT - 1))
#define Va_arg(ArgPointer, T)\
(* (T *)(((ArgPointer) += BOUNDARY(T)) - BOUNDARY(T)))
#define Va_end(ArgPointer)\
ArgPointer = 0
#define Va_start(ArgPointer, A)\
((ArgPointer) = (char *)&(A) + BOUNDARY(A))
int TryIt(char *Arg0, ...)
{
int ArgCount = 0;
Va_list ArgPointer;
Va_start (ArgPointer, Arg0);
for (; *Arg0; ++Arg0)
{
switch (*Arg0)
{
case 'd':
{
Assert(Va_arg(ArgPointer, int) == ++ArgCount);
} break;
case 'f':
{
Assert(Va_arg(ArgPointer, double) == ++ArgCount);
} break;
case 's' :
{
Assert(Va_arg(ArgPointer, char *)[0] == ++ArgCount);
} break;
case 'c' :
{
Assert(Va_arg(ArgPointer, char) == 48 + ++ArgCount);
} break;
}
}
Va_end (ArgPointer);
return(ArgCount);
}
void VargsTest()
{
Assert(TryIt("ddcfd", '\1', 2, '3', 4.0f, 5) == 5);
Assert(TryIt("") == 0);
Assert(TryIt("sfs", "\1", 2.0f, "\3") == 3);
}
[/Code]
I understand most of it, except for the BOUNDARY part. I know for sure Casey talked about this before but I can't recall which episode. I know what it's doing, but I don't understand 100% how it's doing it. i.e. why the "(size + alignment-1) & ~(alignment)" << that part I don't quite get. (I'm not even sure that BOUNDARY is the right name for what it's doing)
Another thing, I'm compiling in x64 mode so the alignment is 8 bytes, but I guess in 32-bit mode it's 4 bytes. Is there a macro in windows that tells us which mode we're compiling in? or do I just pass a BUILD_32 define or something to the compiler and check for #ifdef BUILD_32 in my code?
Any explanation is appreciated!
Thanks!
elxenoanizd/vexe