Solved

What's wrong here.... (Variable Arguement)

Posted on 2003-11-04
13
2,045 Views
Last Modified: 2010-05-18
Hi everybody,
   Can anybody tell me whats wrong in my code..... It runs perfectly fine when i debug it but crashes on execution......

void print(char *cpStart, ... )
{
      va_list Var_List ;
      va_start(Var_List, cpStart) ;

      printf("%s", cpStart) ;

      char *temp ;
      
      while (temp = va_arg(Var_List, char *)) {
            printf("%s", temp)  ;
      }

      va_end(Var_List) ;
}

int main()
{
      print("Hello", " World\n") ;
      print("The", " World", " Is", " Not", " Enough") ;

      return 0 ;
}

Dennis
0
Comment
Question by:dennis_george
  • 3
  • 3
  • 3
  • +3
13 Comments
 

Expert Comment

by:himch
ID: 9677999
Hi Dennis,

The code seems to be working fine on my system.

H.



p.s.: Please check there is a related question also posted in the section. Refer to that as well.
0
 
LVL 16

Expert Comment

by:_nn_
ID: 9678087
Since you're testing for NULL array ending in your print() function, you should be careful to call it like this :

int main()
{
     print("Hello", " World\n", NULL) ;
     print("The", " World", " Is", " Not", " Enough", NULL) ;

     return 0 ;
}

0
 
LVL 5

Author Comment

by:dennis_george
ID: 9679531
Actully I don't like to pass any extra arguement........ like NULL or -1 etc etc....

I want to implement just like printf's implementation........

If the NULL condition check is not right then how will i check the end of my arguement list ???

Dennis
0
 
LVL 15

Accepted Solution

by:
efn earned 25 total points
ID: 9679901
The va_ facilities do not give you any way to tell where the end of the argument list is.  You have to design that yourself.  printf does it by decoding the first argument to tell how many following arguments there should be.  As you may have found, if the following arguments don't conform to what the first one promised, undesirable consequences can follow.

Your current code is based on an assumption that there will be a null pointer at the end of the argument list.  The system is not going to supply that for you, so _nn_ is correct that if you want it work as coded, you must supply the null pointer yourself when you call the function.

If you want it to be just like printf, you have to decode the first string to determine how many following arguments of what types to expect.  As another alternative, you could pass an argument count as the first argument, but I doubt that you want to do that.

--efn
0
 

Expert Comment

by:linuxsub
ID: 9682677
First of all,  _nn_ is correct, and so is efn.

But necessity is the mother of invention, thus god provided C Macros.

Something like this should work for you.:

#include <stdio.h>
#include <stdarg.h>

#define print(args...) real_print(args,0)

void real_print(char *cpStart, ... )
{
        va_list Var_List ;
        int a;
        va_start(Var_List, cpStart) ;

        printf("%s", cpStart) ;

        char *temp ;

        while (temp = va_arg(Var_List, char *)) {
         printf("%s", temp)  ;
        }

        va_end(Var_List) ;
}

int main()
{
        print("Hello", " World\n") ;
        print("The", " World", " Is", " Not", " Enough") ;

        return 0 ;
}
0
 
LVL 5

Author Comment

by:dennis_george
ID: 9684168
Hi linuxsub,

 Do you think a C macro accept Dots('.') as parameter !!!!!

I executed your code but it is giving me the following errors...
: error C2010: '.' : unexpected in macro formal parameter list
: error C2010: '.' : unexpected in macro formal parameter list
: error C2010: '.' : unexpected in macro formal parameter list
: warning C4002: too many actual parameters for macro 'print'


Dennis
0
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 
LVL 16

Expert Comment

by:_nn_
ID: 9685097
"good" compilers do support such a syntax Dennis, unfortunately yours doesn't.

Boiling down efn's comment :
- print("%d%d%s", ...);     // the code in print() determines how many parameters by parsing the first one (here 3)
- print(first, a, b, c, ..., NULL);   // NULL terminated
- print(N, a, b, c, ...); // the first parameter in the list is the total number of parameters
0
 

Expert Comment

by:linuxsub
ID: 9688099
What I suggested was a gcc syntax. But it was just to give you an idea of how to do it. Variable argument macros are implemented differently in different compilers. Which one are you using? Also figure out how to use variable args for macros that you can use in the same manner as I showed.
0
 
LVL 15

Expert Comment

by:efn
ID: 9689754
The 1989 C standard didn't allow variable argument macros.  They were added in the 1999 standard.  To use one according to the standard, plug in "__VA_ARGS__" where you want the variable arguments.  For example:

#define print(...) real_print( __VA_ARGS__ , 0)

Of course, your compiler may or may not support either this feature or a nonstandard variation.

References:

http://home.tiscalinet.ch/t_wolf/tw/c/c9x_changes.html#Preprocessor

http://gcc.gnu.org/onlinedocs/gcc-3.1.1/cpp/Variadic-Macros.html

--efn
0
 
LVL 5

Author Comment

by:dennis_george
ID: 9691841
hi all,
   Does this (macro concept shown above) fall under the ANSII standard ????

Currently i am using VC 6 ......

Dennis
0
 
LVL 15

Expert Comment

by:efn
ID: 9691970
> Does this (macro concept shown above) fall under the ANSII standard ????

Yes, as I noted above.  It's in the 1999 ISO standard (ISO/IEC 9899:1999) and not in the 1989 ANSI standard (ANS X3.159-1989, ISO/IEC 9899:1990).

Microsoft Visual C++ 6.0, which was released in 1998, does not support variable argument macros, as you have found.

--efn
0
 

Expert Comment

by:linuxsub
ID: 9717668
dennis_george,
  If these anwers solve your poblem, award points, or tell us what is that you are stuck at.
0
 

Expert Comment

by:nusdaj
ID: 10418235
It is a highly compiler specific problem. VS provides one example to show its ability to support this. I except it below.

//  Declaration, but not definition, of ShowVar.
void ShowVar( char *szTypes, ... );

void main()
{
    ShowVar( "fcsi", 32.4f, 'a', "Test string", 4 );
}

//  ShowVar takes a format string of the form
//   "ifcs", where each character specifies the
//   type of the argument in that position.
//
//  i = int
//  f = float
//  c = char
//  s = string (char *)
//
//  Following the format specification is a list
//  of n arguments, where n == strlen( szTypes ).

void ShowVar( char *szTypes, ... )
{
   va_list vl;
   int i;

   //  szTypes is the last argument specified; all
   //   others must be accessed using the variable-
   //   argument macros.
   va_start( vl, szTypes );

   // Step through the list.
   for( i = 0; szTypes[i] != '\0'; ++i )
   {
      union Printable_t
      {
         int     i;
         float   f;
         char    c;
         char   *s;
      } Printable;

      switch( szTypes[i] )    // Type to expect.
      {
         case 'i':
            Printable.i = va_arg( vl, int );
            printf( "%i\n", Printable.i );
            break;

         case 'f':
            Printable.f = va_arg( vl, double );
            printf( "%f\n", Printable.f );
            break;

         case 'c':
            Printable.c = va_arg( vl, char );
            printf( "%c\n", Printable.c );
            break;

         case 's':
            Printable.s = va_arg( vl, char * );
            printf( "%s\n", Printable.s );
            break;

         default:
            break;
      }
   }
   va_end( vl );
}
0

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

This tutorial is posted by Aaron Wojnowski, administrator at SDKExpert.net.  To view more iPhone tutorials, visit www.sdkexpert.net. This is a very simple tutorial on finding the user's current location easily. In this tutorial, you will learn ho…
Summary: This tutorial covers some basics of pointer, pointer arithmetic and function pointer. What is a pointer: A pointer is a variable which holds an address. This address might be address of another variable/address of devices/address of fu…
The goal of this video is to provide viewers with basic examples to understand and use structures in the C programming language.
The goal of this video is to provide viewers with basic examples to understand and use switch statements in the C programming language.

707 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

17 Experts available now in Live!

Get 1:1 Help Now