Vararg function and C backend?
Vararg function and C backend?
Hello! Is there a way to make a vararg function/sub when compiling with C backend ("-gen gcc")? I'm doing a logging function that takes format string, format log message via vsnprintf and output it to file. If there is no way to get basic's constructs like "va_first()" working, I'd like to know if there is any possibility to call GCC's builtins from basic code (in this case to get __builtin_va_list pointer)? I'd like to implement it in basic, I don't really want to write it in C and call it from basic code.
Re: Vararg function and C backend?
AFAIR I made a (dirty) workaround on 32 bit LINUX systems by simply using a pointer to the last parameter.
But also check this dkl statement:
You may use a list of optional parameters instead.
But also check this dkl statement:
You may use a list of optional parameters instead.
Re: Vararg function and C backend?
What do you mean? Just make a function that takes like 8 optional parameters? But how to make it eat any parameter type?You may use a list of optional parameters instead.
Yes, I understand that on x64 every function called with fastcall convention (first parameters are passed through registers), but I don't understand why not just simply compile va_first and other commands to GCC's buildins (__builtin_va_list, __builtin_va_start and etc)? Builtins works as expected on most processor architectures.But also check this dkl statement
Re: Vararg function and C backend?
FB's va_* functions are significantly different from C's va_* functions, they can't be translated directly. Additionally the FB va_* functions are very x86-specific. It may be possible to get them working for non-x86, but their semantics would be rather different from x86. Of course, depending on how FB programs use them, they may or may not notice.
FB va_first/va_next return the stack addresses. When arguments are passed in registers, we'd have to load them into temp vars first to be able to return any address at all. I think gcc already does this anyways according to SysV/MS ABIs, but the arguments would not exist in memory consecutively or in the same order as on x86. (i.e., FB programs couldn't treat it as an array anymore)
FB has va_next separate from va_arg, but in C there's only va_arg (which implicitly advances the position). We could work-around that by either completely ignoring va_first/va_next (effectively making them null-ops) for non-x86, or having va_first/va_next read the next argument automatically into a temp var (using C's va_arg) which would then be returned from va_arg. Either way there would be implicit restrictions on when and how often you can call va_first/va_arg/va_next. No more random access as on x86.
Another solution would be to simply add new C-style va_* functions to FB and deprecate the x86-centric ones.
FB va_first/va_next return the stack addresses. When arguments are passed in registers, we'd have to load them into temp vars first to be able to return any address at all. I think gcc already does this anyways according to SysV/MS ABIs, but the arguments would not exist in memory consecutively or in the same order as on x86. (i.e., FB programs couldn't treat it as an array anymore)
FB has va_next separate from va_arg, but in C there's only va_arg (which implicitly advances the position). We could work-around that by either completely ignoring va_first/va_next (effectively making them null-ops) for non-x86, or having va_first/va_next read the next argument automatically into a temp var (using C's va_arg) which would then be returned from va_arg. Either way there would be implicit restrictions on when and how often you can call va_first/va_arg/va_next. No more random access as on x86.
Another solution would be to simply add new C-style va_* functions to FB and deprecate the x86-centric ones.
Re: Vararg function and C backend?
In my opinion this would be the best solution: to deprecate old ones and introduce new keywords that support va_list as GCC builtins for C-backend and LLVM's va_list intrinsics for IR-backend.Another solution would be to simply add new C-style va_* functions to FB and deprecate the x86-centric ones.
I'm also very interested is there any way to "call" GCC's builtin from FreeBasic code? GCC supports a lot of usefull builtins that works on most processor architectures like atomic/sync ones for example, I'd really like to have a way to use them. It seems that I can't just define them as extern functions and use in FreeBasic code.