-2

I was trying to implement function with variable arguments but was getting garbage values as output.I have referred this article before trying to implement on my own.Could anyone help me out with this code as I am unable to understand what's wrong in this code.

/* va_arg example */
#include <stdio.h>      /* printf */
int FindMax (int n, ...)
{
    int i,val,largest,*p;
    p=&n;
    p+=sizeof(int);
    largest=*p;
    for (i=1;i<n-2;i++)
    {
        p+=sizeof(int);
        val=*p;
        largest=(largest>val)?largest:val;
    }
    return largest;
}
int main ()
{
    int m;
    m= FindMax (7,702,422,631,834,892,104,772);
    printf ("The largest value is: %d\n",m);
    return 0;
}

1 Answers1

3

The problem is that you try to access locations on the stack directly where you assume to find your arguments. Calling conventions are machine- and sometimes compiler-specific and an implementation detail you can never rely on, so probably your arguments are not found on the stack where you assume they are. In terms of C, your code just invokes undefined behavior

Solution: use stdarg.h for accessing the arguments, that's what it's there for.

#include <stdio.h>      /* printf */
#include <stdarg.h>

int FindMax (int n, ...)
{
    va_list ap;
    int i,val,largest;

    va_start(ap, n); // <- ap is the argument pointer, this initializes it
                     //    based on the last non-variadic argument.

    largest=0;
    while (n--)
    {
        val = va_arg(ap, int); // <- fetch argument and advance pointer
        largest=(largest>val)?largest:val;
    }
    va_end(ap); // done with argument pointer

    return largest;
}
int main ()
{
    int m;
    m= FindMax (7,702,422,631,834,892,104,772);
    printf ("The largest value is: %d\n",m);
    return 0;
}
  • Thank you @Felix Palmen but I have another doubt , if I wanted to access an element at some index 'i' do I need to traverse from the first element using va_arg (or need to store it in an array)or can you suggest any other method to access the va_list. – Ravi Teja Namballa Jun 16 '17 at 09:50
  • 1
    @RaviTejaNamballa Yes, that's the only thing the C standard specifies... –  Jun 16 '17 at 09:51
  • `int main ()` is an obsolecence signature. Use prototype-style declarators! – too honest for this site Jun 16 '17 at 09:53
  • @Olaf it's acceptable and I won't change more in OPs code than absolutely necessary to solve the problem ;) –  Jun 16 '17 at 09:55
  • @FelixPalmen: Sorry, but that's a lame excuse. Read the standard. It is subject to be removed from the standard (I'm aware about the notorious slowness of the commitee, though). Why stick to ancient coding styles? – too honest for this site Jun 16 '17 at 09:59
  • 1
    @Olaf *supposed to* is not relevant here. Let's just focus on the question and the solution ... –  Jun 16 '17 at 10:00
  • Answers should also enhance code quality. That's one of the missions of this site. – too honest for this site Jun 16 '17 at 10:02
  • 1
    @Olaf downvote if you like, I will keep my answers on point and I don't see any "bad quality" with this. –  Jun 16 '17 at 10:05
  • Is it not possible to do it without stdarg.h? – Ravi Teja Namballa Jun 16 '17 at 10:06
  • 1
    @RaviTejaNamballa not according to C. Don't you understand this response? The point is, there are a LOT of different calling conventions, your arguments could even reside in processor registers (so you have no way to access them from C, only using assembly code) –  Jun 16 '17 at 10:07
  • 1
    @RaviTejaNamballa of course, you could use your own code for **one specific machine and compiler** and given this machine really has all the arguments on the stack, it could even work without assembly. It's just not a "C program" any more (contains behavior that's *undefined* according to the C standard) –  Jun 16 '17 at 10:09
  • @RaviTejaNamballa: The actual question is: **Why** don't you want to use `stdarg.h`? This is one of the headers _any_ C implementation has to provide, there is no point in not using it! – too honest for this site Jun 16 '17 at 10:34
  • @Olaf : Well I am just a beginner started learning C recently and I was trying to understand how these functions are working.I got a good explanation from Felix Palmen .I will use stdarg.h as you mentioned.Thank You. – Ravi Teja Namballa Jun 16 '17 at 10:47