Page 1 of 1
Unlimited Arguments
Posted: Wed Nov 02, 2005 5:20 pm
by C-Coder
hi guys
i want to get the parameters of a function with unlimited arguments
here is my code, it worked but i get warnings :
arg.c:6: warning: return type defaults to `int'
arg.c: In function `main':
arg.c:8: warning: control reaches end of non-void function
arg.c: In function `myfunc':
arg.c:13: warning: initialization makes pointer from integer without a cast
arg.c:14: warning: assignment makes pointer from integer without a cast
arg.c:15: warning: assignment makes pointer from integer without a cast
arg.c:16: warning: assignment makes pointer from integer without a cast
any one have a better solution ? or solve me these warnings
Code: Select all
#include <stdio.h>
void myfunc(char *, ...);
int get_param(int, int);
main()
{
myfunc("hi how are you", 5, 6);
}
void myfunc(char *str, ...)
{
int *d1,*d2,*d3;
int *address=(int)&str;
d1=(int)get_param(0, (int)*address);
d2=(int)get_param(1, (int) address);
d3=(int)get_param(2, (int) address);
printf("%s\n", (char *)d1);
printf("%d\n", (int)*d2);
printf("%d\n", (int)*d3);
}
int get_param(int n, int addr)
{
int address;
address=(addr)+(n*4);
return address;
}
Re:Unlimited Arguments
Posted: Wed Nov 02, 2005 6:08 pm
by kataklinger
For the first and for the secon on you should add "return 0;" at the end of main(), or define main as "void main()", because default return type is int not void. And for the rest you should do (int*) casting not (int).
Re:Unlimited Arguments
Posted: Wed Nov 02, 2005 7:45 pm
by C-Coder
My latest code worked, but it didn't print the floating numbers !
What should i do in order to make my code print the floating numbers ?
Code: Select all
#include <stdio.h>
void myfunc(char *, ...);
int get_param(int, char *);
int main()
{
myfunc("hi how are you", 5, 6, 'H', -118.625);
return 0;
}
void myfunc(char *str, ...)
{
char *d0,*d1,*d2,*d3,*d4;
d0=str;
d1=(char *)get_param(1, (char *)&str);
d2=(char *)get_param(2, (char *)&str);
d3=(char *)get_param(3, (char *)&str);
d4=(char *)get_param(4, (char *)&str);
printf("1st Argument: %s\n", d0);
printf("2nd Argument: %d\n", (int)*d1);
printf("3rd Argument: %d\n", (int)*d2);
printf("4th Argument: %c\n", (char)*d3);
printf("5th Argument: %f\n", (float)*d4);
}
int get_param(int n, char *addr)
{
return (int)((addr)+(n*4));
}
Re:Unlimited Arguments
Posted: Wed Nov 02, 2005 8:22 pm
by C-Coder
so i need a ftoa() function, does gcc or g++, libc have one ?
Re:Unlimited Arguments
Posted: Wed Nov 02, 2005 9:34 pm
by AR
Using GCC builtins:
Code: Select all
void myfunc(char *format, ...)
{
__builtin_va_list va;
__builtin_va_start(va, format);
printf("1st Argument: %s\n", __builtin_va_arg(va, char*));
printf("2nd Argument: %d\n", __builtin_va_arg(va, int));
printf("3rd Argument: %d\n", __builtin_va_arg(va, int));
printf("4th Argument: %c\n", __builtin_va_arg(va, int));
printf("5th Argument: %f\n", __builtin_va_arg(va, float));
__builtin_va_end(va);
}
Re:Unlimited Arguments
Posted: Wed Nov 02, 2005 9:53 pm
by C-Coder
ya i knew about that but i was afraid of compatability with other c compilers,
Code: Select all
printf("5th Argument: %f\n", __builtin_va_arg(va, float));
should changed to
Code: Select all
printf("5th Argument: %f\n", __builtin_va_arg(va, double));
gcc reserves space for float as double (64-bit) and char as int (32-bit) in the unlimited arguments (...)
This code gives segmentation fault:
Code: Select all
printf("1st Argument: %s\n", __builtin_va_arg(va, char*));
thanks very much AR
Re:Unlimited Arguments
Posted: Wed Nov 02, 2005 10:10 pm
by AR
The first line seg faults cause it was meant to be:
Code: Select all
printf("1st Argument: %s\n", str);
There is some complex macro you can use but I prefer:
Code: Select all
#include <stdarg.h>
int myfunc(char *str, ...)
{
va_list va;
va_start(va, str);
...
va_end(va);
}
stdarg is part of the freestanding environment for GCC and assumably other compilers as well.
Re:Unlimited Arguments
Posted: Wed Nov 02, 2005 11:27 pm
by C-Coder
yup that works
thanks AR
but why the traditional way i used (using pointer) don't work for float ?
another thing, not all compilers support __builtin_va_list, this code ofcourse worked on gcc but failed on tinycc.
thanks again AR
Re:Unlimited Arguments
Posted: Wed Nov 02, 2005 11:32 pm
by C-Coder
sorry AR
it also worked on tcc, i forgot to include stdarg.h
thanks again AR
Re:Unlimited Arguments
Posted: Thu Nov 03, 2005 3:34 pm
by nick8325
C-Coder wrote:
but why the traditional way i used (using pointer) don't work for float ?
I think there is a mistake in your code:
should be
.
The first works out *d4 - which is a char - and turns it into a float. Since chars are only one byte long and floats are (on x86, normally) four, that's not what you want.
The second turns d4 into a pointer to float, and then works out the value of the actual float at the location.
By the way, the code you've written is the same sort of thing that will happen internally in va_arg. But va_arg is processor-specific and does a few more things - for example, a double on x86 is 8 bytes long, so if get_param(n, addr) is the address of the float, the next variable will be at get_param(n+2, addr). va_arg (which is normally a macro) will look at the size of the type to decide how much to skip. There are also alignment problems...but it is not really very different.
Re:Unlimited Arguments
Posted: Sun Nov 06, 2005 5:41 pm
by C-Coder
nick8325 wrote:
C-Coder wrote:
but why the traditional way i used (using pointer) don't work for float ?
I think there is a mistake in your code:
should be
ya thanks, it worked but it should be
gcc manual says that gcc reserve 64-bit for float when passed through (...)
so in unlimited arguments the float == double && char == int in the reserved space.
Re:Unlimited Arguments
Posted: Sun Nov 06, 2005 5:44 pm
by C-Coder
So the latest working version of code is:
Code: Select all
#include <stdio.h>
void myfunc(char *, ...);
int get_param(int, char *);
int main()
{
myfunc("hi how are you", 5, 6, 'H', -118.625);
return 0;
}
void myfunc(char *str, ...)
{
char *d0,*d1,*d2,*d3,*d4;
d0=str;
d1=(char *)get_param(1, (char *)&str);
d2=(char *)get_param(2, (char *)&str);
d3=(char *)get_param(3, (char *)&str);
d4=(char *)get_param(4, (char *)&str);
printf("1st Argument: %s\n", d0);
printf("2nd Argument: %d\n", *(int *)d1);
printf("3rd Argument: %d\n", *(int *)d2);
printf("4th Argument: %c\n", *(int *)d3);
printf("5th Argument: %f\n", *(double *)d4);
}
int get_param(int n, char *addr)
{
return (int)((addr)+(n*4));
}