va_arg (ap,int(*)()) 

here, ap is the va_list type variable and it is started with va_start() already.

the place where i have read this said that this is wrong and you have to typedef it first , then you can extract the pointer to a function from the va_arg(). why is it so ? if i can extract int,char* this way, then why can't i do this ? thanks.

Recommended Answers

All 18 Replies

http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf

Navigate to section 7.16.1.1-2 and you'll find this sentence: "The parameter type shall be a type name specified such that the type of a pointer to an object that has the specified type can be obtained simply by postfixing a * to type."

the place where i have read this said that this is wrong

Then you read the wrong article -- see the example here

Then you read the wrong article -- see the example here

That page says the same thing. ;)

unless I missed it that page says nothing about typedef. The example program certainly doesn't use it.

no no sir(s)! the place from where i have read , it says you can use it for int,float,double. char*, float* etc, but they have given an example in which they have used this statement given above and saying that this is not way to extract a pointer to a function. they have firstky typedef it and then extracting the pointer to the function. they are saying this thing specifically for pointer to functions. (I don't know if there is any exception like this for something else also). now tell the solution.

You did miss it. Simple types aren't a problem, but complex types like nitin's example are, Reread the description of the type parameter in your link and it will correspond to my quote from the standard. You're correct that it says nothing about typedef, but keep in mind that int(*)()* is meaningless.

yeah sir. that's what i am saying. that it is not problem for float and all, but it is problem for pointer to functions. can you explain why it is so and what are the other exceptions to this ? thanks a lot sir.

can you explain why it is so

This is one of those cases where the reason why is "because the standard says so". Seriously, sometimes it's that simple. It probably has to do with difficulty in parsing for the compiler, but the reason why is totally irrelevant for you as the end-developer. It just is, and you have no choice but to comply.

As for other exceptions, the standard explains in adequate detail. If you can't say <type>*, you must use a typedef. End of story.

Oh I see now. You could do something like below. I just copied the code from the link I gave previously and added pointer to a function. According to standards this may not be portable especially on systems where sizeof(pointer) is not the same as sizeof(function pointer).

/* va_arg example */
#include <stdio.h>      /* printf */
#include <stdarg.h>     /* va_list, va_start, va_arg, va_end */
#include <iostream>

int foo()
{
    std::cout << "Hello from foo\n";
    return 1;
}

int FindMax (int n, ...)
{
  int i,val,largest;
  va_list vl;
  va_start(vl,n);
  largest=va_arg(vl,int);
  for (i=1;i<n;i++)
  {
    val=va_arg(vl,int);
    largest=(largest>val)?largest:val;
  }
  //
  // extract pointer to a function
  int (*fn)() = (int (_cdecl *)())va_arg(vl,int*);
  // now call that function
  fn();
  va_end(vl);
  return largest;
}

int main ()
{
  int m;
  m= FindMax (7,702,422,631,834,892,104,772, foo);

  printf ("The largest value is: %d\n",m);
  return 0;
}

ohh... ok , i will grasp it as standard says. but like this (pointers to functions), what else i need to typedef like this ?

int (fn)() = (int (_cdecl *)())va_arg(vl,int);

All I can say to that is ewwww. There's a hyoooge assumption that pointers to functions are equivalent to pointers to int. Very risky, and non-portable at best.

what else i need to typedef like this ?

Pointers to arrays come to mind.

There's a hyoooge assumption that pointers to functions are equivalent to pointers to int. Very risky, and non-portable at best.

Agree, but it's a solution on systems where the sizes are the same. I don't think I ever had a reason to do that in any program I wrote over 20+ years. But that doesn't mean someone else hasn't.

As for being risky -- using vargs is always risky because it's impossible for the compiler to validate parameter types with actual arguments whether they are pointers or POD.

but like this (pointers to functions), what else i need to typedef like this ?

You don't NEED typedef's at all. They are useful at times, not are never required.

statements of you and James sir are little bit contradictory. i can't offsense any one of you. can you please clearify this ? thanks alot.

statements of you and James sir are little bit contradictory.

Rest assured, I'm correct and AD will realize this eventually. In this particular case, typedef is absolutely required to be strictly correct for complex types. The standard is very clear about it, but it is an edge case.

i really really appreciate your extent of confidence. because many times i know i am 101% correct, but still i say "am in doubt" because person in front of me is saying this again and again. i have seen that you don;t come under this category.

If you're absolutely sure you're correct, don't be afraid to say so. The worst thing that could happen is someone will irrationally hate you when you surely prove them to be incorrect.

Of course, if you're sure you're correct but you're not, be willing to accept when someone proves you wrong. ;)

yoo! nice... and one thing, this thing always improves one's confidence. when u say something which you know you are damn correct and sure about that thing, and you are able to prove that you are correct, next time you will hit that with double confidence. i know this thing, but never able to implement this. :( sorry to myself.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.