Ind Posted November 9, 2012 Share Posted November 9, 2012 for no particular reason at ~4:20 am i stumbled upon http://svn.netlabs.org/repos/gl2/include/cstdarg and then realized all the va_stuff business rathena makes use of in all map_foreachin<whatever> procedures, for instance: map_foreachinmap for(i=blockcount;i<bl_list_count;i++) if(bl_list[i]->prev) { va_list ap; va_start(ap, type); returnCount += func(bl_list[i], ap); va_end(ap); } wouldnt va_list ap; va_start(ap, type); for(i=blockcount;i<bl_list_count;i++) if(bl_list[i]->prev) { returnCount += func(bl_list[i], ap); } va_end(ap); be way more efficient? the arguments being passed are never changed during the loop, whats the point in recreating the damn thing bl_list_count times? Link to comment Share on other sites More sharing options...
GreenBox Posted November 9, 2012 Share Posted November 9, 2012 There is no practical performance gain as va_start just do some pointer arithmetic and va_end does nothing, btw the code will be more beautiful if the va_list were created just one time. Link to comment Share on other sites More sharing options...
lekkereten Posted November 9, 2012 Share Posted November 9, 2012 There is no practical performance gain as va_start just do some pointer arithmetic and va_end does nothing, btw the code will be more beautiful if the va_list were created just one time. +1 Link to comment Share on other sites More sharing options...
Ind Posted November 20, 2012 Author Share Posted November 20, 2012 After some tests I realized va_arg moves the va_lists' internal offset whenever you retrieve a arg (moves equivalent to the size of that arg), so indeed the va_start must be re-run (we can't simply zero the offset because the offset field is platform-dependant). I'll move the va_list outside the loop as you suggested Link to comment Share on other sites More sharing options...
GreenBox Posted November 20, 2012 Share Posted November 20, 2012 Actually if it is passed as a argument it wont change on the next use, btw the va is just a pointer on the stack to the arguments. Link to comment Share on other sites More sharing options...
Ind Posted November 20, 2012 Author Share Posted November 20, 2012 Actually if it is passed as a argument it wont change on the next use, btw the va is just a pointer on the stack to the arguments. but va_list type is also system dependent at times it is a pointer, at times it isnt: (be aware its 5am i might have missed something D: bear with me) #if defined(__PPC__) #if defined(__NT__) typedef char * __va_list; #else typedef struct { char __gpr; char __fpr; char __reserved[2]; char *__input_arg_area; char *__reg_save_area; } __va_list; #endif #elif defined(__AXP__) typedef struct { char *__base; int __offset; } __va_list; #elif defined(__MIPS__) typedef struct { char *__base; int __offset; } __va_list; #elif defined(__HUGE__) || defined(__SW_ZU) typedef char _WCFAR *__va_list[1]; #else typedef char *__va_list[1]; #endif it appears my table from above is outdated; I've used gdb to take a look at my current one and its like this (not like any of the above): ap = {{ gp_offset = 24, fp_offset = 48, overflow_arg_area = 0x7fff5fbfc500, reg_save_area = 0x7fff5fbfc400 }} I've found some more about the above one in Apple's Darwin stuff: http://opensource.apple.com/source/cc/cc-798/cc/ginclude/va-ppc.h Link to comment Share on other sites More sharing options...
GreenBox Posted November 20, 2012 Share Posted November 20, 2012 Strange, atleast on x86 systems it should be just a pointer walking through the stack. Link to comment Share on other sites More sharing options...
lekkereten Posted November 29, 2012 Share Posted November 29, 2012 What could be implemented was done in r16933 Link to comment Share on other sites More sharing options...