VA_LIST

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
zack

VA_LIST

Post by zack »

Hi everybody.
i tried yesterday to make a function with a va_list.

this is the function prototype:

Code: Select all

void       DrawBitmap      (GUIBitmap *, int32_t, int32_t, uint8_t, ...);
if the last uint8_t is DRAW_TRANSPARENT (0x2), then the function request one parameter more. i tried to get it with this peace of code here:

Code: Select all

#typedef unsigned long uint32_t;
void    DrawBitmap(GUIBitmap *_bmp, int32_t _x, int32_t _y, uint8_t _mode, ...)
{
   va_list args;
   va_start(args, _mode);

   uint32_t transp = va_arg(args, uint32_t); //needed only if _mode == DRAW_TRANSPARENT

   va_end(args);
};
but however this one didn't work. :(
what made i wrong?
could you help me? thx

thx for help.

Code: Select all

#ifndef STDARG_H
#define STDARG_H

typedef unsigned char *va_list;

#define STACKITEM int

#define va_start(AP,LASTARG)                                  \
  ( AP = (( va_list ) & ( LASTARG ) + VA_SIZE( LASTARG )))

#define va_arg(AP,TYPE)                                       \
  (AP+=__va_rounded_size(TYPE),*((TYPE *)(AP-__va_rounded_size(TYPE))))

#define __va_rounded_size(TYPE)                               \
  (((sizeof(TYPE)+sizeof(int)-1)/sizeof(int))*sizeof(int))

#define VA_SIZE(TYPE)                                         \
  ((sizeof(TYPE)+sizeof(STACKITEM)-1)&~(sizeof(STACKITEM)-1))

#define va_end(AP) \
   ( AP = (void *)(0) )
  
#endif
Cjmovie

Re:VA_LIST

Post by Cjmovie »

Well, I'm really no expert on define macros....(Yeah, I've no clue ^_^)

So, the obvious problem I can point out is that anything you send to a function, no matter what size it is, will ALWAYS be 32-bits on an x86 machine, meaning your VA_SIZE shouldn't return the size of something to add to the end of the stack, as it will vary from the 32 bits....instead, always add 4 bytes.

Of course, I could be totally wrong.
zack

Re:VA_LIST

Post by zack »

well, i'd "copied" (rewritten) this part of a tutorial. and i've seen other code snippets which does the same. but i'll try it.
thx
AR

Re:VA_LIST

Post by AR »

What exactly do you mean by "doesn't work"? It's not very helpful with programming problems when people just say "doesn't work"... Do you mean it doesn't compile? Outputs rubbish? Page faults?

In the former case, you have a 'pound' sign ("#") in front of your typedef, typedef is a C directive not a preprocessor directive. In the second case, I don't like those sorts of complex macros so I prefer the easy way out using the GCC builtin directives:

Code: Select all

#define va_start(v, f) __builtin_va_start(v, f);
#define va_end(v)       __builtin_va_end(v);
#define va_arg(v, a)   __builtin_va_arg(v, a);
You can also just "#include <stdarg.h>".
zack

Re:VA_LIST

Post by zack »

the output is rubbish.... a.expl. if i give to it a parameter 0x00 (32bit) the the content of the va_arg(_mode, int) is something like 0xXXXX00. but the code shouldn't be wrong...

thats the output of your code:

Code: Select all

gui/uiBitmap.c: In function `DrawBitmap':
gui/uiBitmap.c:38: error: incompatible type for argument 1 of `__builtin_va_start'
gui/uiBitmap.c:56: error: incompatible type for argument 1 of `__builtin_va_end'
gui/uiBitmap.c:43: error: first argument to `va_arg' not of type `va_list'
make.exe: *** [c] Error 1
Error open kernelc.bin
argh.. :)
thx!
AR

Re:VA_LIST

Post by AR »

Sorry, you will also need:

Code: Select all

#define va_list     __builtin_va_list
zack

Re:VA_LIST

Post by zack »

yeah, this one works now... but what was the different?
works this gcc builtin on all versions? (djgpp, cygwin, linux, windows...)

thx
AR

Re:VA_LIST

Post by AR »

It should work on all GCC 3.x/4.x. If you want to support multiple compilers then I recommend using "#include <stdarg.h>" instead of defining your own macros.
Anon00000100

Re:VA_LIST

Post by Anon00000100 »

As far as I can see, <stdarg.h> was what he was trying to implement in the first place...
AR

Re:VA_LIST

Post by AR »

Anon00000100 wrote: As far as I can see, <stdarg.h> was what he was trying to implement in the first place...
I am suggesting to not implement a stdarg.h, just to use the one that came with the compiler (stdarg.h is part of the freestanding GCC environment [ie. it's a system header] and should be in other compilers as well).
Post Reply