Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. Implementing variable length parameter - variadic funetion

Implementing variable length parameter - variadic funetion

Scheduled Pinned Locked Moved C / C++ / MFC
helptutorialquestionc++design
6 Posts 3 Posters 2 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • L Offline
    L Offline
    Lost User
    wrote on last edited by
    #1

    I screwed-up and started posting code problem in "quick answers' and I am sorry for that. So I cut and paste it here to continue and hopefully resolve the issue

    Not much of an improvement - more questions.
    I am using the tutorial example and it is complaining about
    missing "num" .
    I am passing QString as variable number of parameters

    Copy Code

    QString parameter = " TEST message ";
    ProcessMessage_Variadic(1, " TEST message ");

    So what is the problem - the macro
    Expand ▼ Copy Code

    va_arg

    ?

    declaration
    void ProcessMessage_Variadic(int num,...);

    usage
    ProcessMessage_Variadic(1, " TEST message ");

    definition
    void RemoteSelector::ProcessMessage_Variadic (int num,...)
    {

     ui->textEdit->append( "RemoteSelector::ProcessMessage\_Variadic");
     QString s = "DUMMY";
     va\_list valist;
     double sum = 0.0;
     int i;
    
     /\* initialize valist for num number of arguments \*/
     va\_start(valist, num);
    
     /\* access all the arguments assigned to valist \*/
     for ( i = 0; i < num; i++) {
         s = va\_arg(valist, num);
    

    ERROR HERE
    /home/qy/Qt/Examples/Qt-5.15.0/bluetooth/btchat/remoteselector.cpp:396: error: unknown type name 'num'

       ui->textEdit->append(s); 
     }
    
     /\* clean memory reserved for valist \*/
     va\_end(valist);
    
     //return sum/num;
    

    }

    K 1 Reply Last reply
    0
    • L Lost User

      I screwed-up and started posting code problem in "quick answers' and I am sorry for that. So I cut and paste it here to continue and hopefully resolve the issue

      Not much of an improvement - more questions.
      I am using the tutorial example and it is complaining about
      missing "num" .
      I am passing QString as variable number of parameters

      Copy Code

      QString parameter = " TEST message ";
      ProcessMessage_Variadic(1, " TEST message ");

      So what is the problem - the macro
      Expand ▼ Copy Code

      va_arg

      ?

      declaration
      void ProcessMessage_Variadic(int num,...);

      usage
      ProcessMessage_Variadic(1, " TEST message ");

      definition
      void RemoteSelector::ProcessMessage_Variadic (int num,...)
      {

       ui->textEdit->append( "RemoteSelector::ProcessMessage\_Variadic");
       QString s = "DUMMY";
       va\_list valist;
       double sum = 0.0;
       int i;
      
       /\* initialize valist for num number of arguments \*/
       va\_start(valist, num);
      
       /\* access all the arguments assigned to valist \*/
       for ( i = 0; i < num; i++) {
           s = va\_arg(valist, num);
      

      ERROR HERE
      /home/qy/Qt/Examples/Qt-5.15.0/bluetooth/btchat/remoteselector.cpp:396: error: unknown type name 'num'

         ui->textEdit->append(s); 
       }
      
       /\* clean memory reserved for valist \*/
       va\_end(valist);
      
       //return sum/num;
      

      }

      K Offline
      K Offline
      k5054
      wrote on last edited by
      #2

      Member 14968771 wrote:

      error: unknown type name 'num'

      That's pretty clear, I think. But here's the scoop - when pulling arguments out of a va_list, the second argument to va_arg is a type, not a variable name. So in your case this should be

      QString s;
      for(int i = 0; i < num; ++i)
      s = va_arg(args, QString)

      Keep Calm and Carry On

      L Richard Andrew x64R 2 Replies Last reply
      0
      • K k5054

        Member 14968771 wrote:

        error: unknown type name 'num'

        That's pretty clear, I think. But here's the scoop - when pulling arguments out of a va_list, the second argument to va_arg is a type, not a variable name. So in your case this should be

        QString s;
        for(int i = 0; i < num; ++i)
        s = va_arg(args, QString)

        Keep Calm and Carry On

        L Offline
        L Offline
        Lost User
        wrote on last edited by
        #3

        Many thanks you saved me from hunting for the macro definition. So how would it work if the passed parameters are of mixed type ? Or is it even possible to have mixed parameters?

        K 1 Reply Last reply
        0
        • K k5054

          Member 14968771 wrote:

          error: unknown type name 'num'

          That's pretty clear, I think. But here's the scoop - when pulling arguments out of a va_list, the second argument to va_arg is a type, not a variable name. So in your case this should be

          QString s;
          for(int i = 0; i < num; ++i)
          s = va_arg(args, QString)

          Keep Calm and Carry On

          Richard Andrew x64R Offline
          Richard Andrew x64R Offline
          Richard Andrew x64
          wrote on last edited by
          #4

          Where is i used in the call to va_arg?

          The difficult we do right away... ...the impossible takes slightly longer.

          K 1 Reply Last reply
          0
          • L Lost User

            Many thanks you saved me from hunting for the macro definition. So how would it work if the passed parameters are of mixed type ? Or is it even possible to have mixed parameters?

            K Offline
            K Offline
            k5054
            wrote on last edited by
            #5

            This is the mechanism that printf() uses to pass mixed arguments in, so its definitely doable. printf uses its format string to help unpack the argument list, but there are other ways. You could use a simplified format string like "sddi", showing that the unspecified arguments are a string, two doubles and an int. Another option might be to use an indicator e.g

            #define ARG_INT 1
            #define ARG_LONG 2
            #define ARG_DOUBLE 3
            #define ARG_CHAR 4
            #define ARG_STRING 5
            // ...
            #define ARG_END -1

            int var_arg_fn(int arg, ...)
            {
            va_ist args;
            va_start(args, arg);
            while(arg != ARG_END) {
            switch(arg) {
            case ARG_INT :
            {
            int i = va_arg(args, int);
            // ...
            break;
            }
            case ARG_DOUBLE :
            {
            double d = va_arg(args, double);
            // ...
            break;
            }
            // ... etc ...
            default:
            // handle error, maybe
            }
            arg = va_arg(args, int);
            }
            }
            // and then call it like
            var_arg_fn(ARG_INT, 1, ARG_DOUBLE, 3.2, ARG_STRING, strvar, ARG_END);

            I'm sure if you think about it, you can come up with something that suits your needs. But since you're using C++ now might be the time to venture into the world of variadic fuction templates. Google for that and check out one or more of the tutorials and/or examples. It might be a better fit than trying to wrap things back down to C stdargs. Update: Here's a video on variadic templates that may help [C++ Weekly - Ep 6 Intro To Variadic Templates - YouTube](https://www.youtube.com/watch?v=o1EvPhz6UNE&list=PLs3KjaCtOwSZ2tbuV1hx8Xz-rFZTan2J1&index=6)

            Keep Calm and Carry On

            1 Reply Last reply
            0
            • Richard Andrew x64R Richard Andrew x64

              Where is i used in the call to va_arg?

              The difficult we do right away... ...the impossible takes slightly longer.

              K Offline
              K Offline
              k5054
              wrote on last edited by
              #6

              Its only used as a loop counter. If you prefer we could do

              while(num--)
              {
              s = val_arg(args, QString);
              // ...
              }

              That, of course alters the value of num, so if you need to know how many args were passed in, or need to traverse the argument list again, you don't want to do that.

              Keep Calm and Carry On

              1 Reply Last reply
              0
              Reply
              • Reply as topic
              Log in to reply
              • Oldest to Newest
              • Newest to Oldest
              • Most Votes


              • Login

              • Don't have an account? Register

              • Login or register to search.
              • First post
                Last post
              0
              • Categories
              • Recent
              • Tags
              • Popular
              • World
              • Users
              • Groups