Hello...
is there a nice and portable way of changing some variable arguments, and then passing these changed arguments to the same function as recursion??
Here's a non-general example:
#include <stdio.h>
int go(int num, ...)
You declared go() as returning a value of type 'int'; yet nowhere in
your code does it ever return a value. This is permitted if no call to
go() ever attempts to use the value which go() fails to return; but it's
a bad idea to rely upon that fact. If the function never returns a
value, its declaration should say so; if the declaration says it will
return a value, it should actually do so. I'm not sure which way of
fixing this is the one appropriate to your use.
{
int *p = #
int *p2 = p;
int i, n;
for (i = 1; i <= num; ++i)
printf("%d ", *(++p2));
This is undefined behavior. p points at only a single int. The standard
specifies that a pointer to a single int must be treated, for purposes
of pointer arithmetic, as if it were pointer to the only element of an
array of int with a length of 1. Therefore, p+i has defined behavior for
i == 0 or 1, but not for any other value of i. *(p+i) has defined
behavior only for i==0.
putchar('\n');
for (p2 = p+num; p2 > p; --p2) {
When num has any value other than 0 or 1, the expression p+num has
undefined behavior.
Since you only reach this line if p2>p, *p2 has undefined behavior, too.
If the code had defined behavior, the parentheses would be unnecessary.
if (n > 0) {
--(*p2);
//recurr
p2 = p+1;
go(num, *p2, *(p2+1), *(p2+2)); // lucky me... 4 total arguments
The last three arguments of go() all have undefined behavior.
My best guess is that you're assuming that *(&num+i), for i from 1 to
num, will retrieve the values of any additional int arguments of go().
I've used implementations of C where that would work; presumably it
works on the implementation you're using, or you wouldn't have even come
up with code so badly broken. However, it's not guaranteed to work, and
there are many real systems where it will fail catastrophically, which
is why that's NOT how you're supposed to access the additional arguments
of a variadic function.
break;
}
}
}
int main(void)
{
go(3, 3, 3, 3);
return 0;
}
As is shown in the comment above, I'm just lucky with invoking 4 arguments in the recursion.
What could I do, if I don't know the number of arguments and want recursion?
Given that all of your arguments are of type 'int', using a pointer to
the first element of an array of 'int', as you discussed in your other
message, is probably the best way to handle that. However, if the
arguments were not all of the same type, that wouldn't work.
Here's a re-write of your code that has defined behavior, and
demonstrates the correct way for a function with variable arguments to
extract them. To keep it reasonably close to your original code, I
change p from a pointer at a non-existent array into the name of an
actual array. Properly, it should validate that num<4; if num>3, the
recursive call to go() has undefined behavior. I wasn't sure what you'd
want to do in that case, so I left it up to you.
#include <stdarg.h>
#include <stdio.h>
void go(int num, ...)
{
if(num <= 0)
return;
va_list ap;
int p[num + 1];
p[0] = num;
va_start(ap, num);
for(int i=1; i<num+1; i++)
{
p
= va_arg(ap, int);
printf("%d ", p);
}
va_end(ap);
putchar('\n');
for(int *p2 = p + num; p2 > p; --p2)
{
if(*p2 > 0)
{
--(*p2);
go(num, p[1], p[2], p[3]);
break;
}
}
}
int main(void)
{
go(3, 3, 3, 3);
return 0;
}