Thread: variable argument

  1. #1
    Registered User
    Join Date
    Jan 2017
    Posts
    9

    variable argument

    hey, I'm trying to write(for a micro-controller) a function that takes in one argument along with an unknown number of arguments. For now I'm testing on an arduino, so there will be some arduino functions. My problem is this: I can't get the individual arguments. The value for all arguments(except the first) is between 0x00 and 0xFF and I want to pass each of them through an spi.transfer function. for instance the arguments are (0, 0x24, 0x63) (the first argument in my case tells me the number of bytes I am expecting to receive, so we can ignore it), so I want 0x24 to be passed via spi.transfer and after pass 0x63.
    Code:
    uint32_t SCOM (int Size, int x, ...){
      va_list valist;
      va_start(valist, x);                          
      for (int i = 0;  i < x; i++){              
        Serial.println((valist, i), BIN);
        SPI.transfer( (valist, i) );
        }
      if (Size != 0){                               
        for ( int i = 0;  i < Size; i++ ){
          uint32_t data;
          if (i == 0){
            data = SPI.transfer(0xff);
            if (Size == 1){ return data; }
          }
          else{
            data |= (uint32_t)SPI.transfer(0xff) << (8 * i);
            }
          return data;
        }
      }
      if (Size == 0){return NULL;}
      else {Serial.println("ERROR SCOM format: unsigned int to be received, register");}
    }
    Last edited by kiyoshi7; 01-07-2017 at 07:23 PM.

  2. #2
    Old Took
    Join Date
    Nov 2016
    Location
    Londonistan
    Posts
    121
    Is the missing va_end(valist) the issue? You must match a va_start with a va_end.

  3. #3
    Registered User
    Join Date
    Jan 2017
    Posts
    9
    Quote Originally Posted by Hobbit View Post
    Is the missing va_end(valist) the issue? You must match a va_start with a va_end.
    sorry, I edited it a little when I posted so I accidentally left out. well when I run this function it always passes 0 through spi.transfer instead of the argument. So, I don't think I'm using this correctly.

  4. #4
    Old Took
    Join Date
    Nov 2016
    Location
    Londonistan
    Posts
    121
    Yes you are not, you need to use va_arg to access individual arguments from the list.

  5. #5
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    > Serial.println((valist, i), BIN);
    > SPI.transfer( (valist, i) );
    You need to call va_arg to access individual arguments.

    (valist,i) is a comma expression, who's value is just i.
    Sufficient compiler warnings should tell you this.
    Code:
    int main()
    {
      printf("%d\n", (1,2,3) );
      return 0;
    }
    
    $ gcc -Wall main.c
    main.c: In function ‘main’:
    main.c:31:20: warning: left-hand operand of comma expression has no effect [-Wunused-value]
       printf("%d\n", (1,2,3) );
                        ^
    main.c:31:22: warning: left-hand operand of comma expression has no effect [-Wunused-value]
       printf("%d\n", (1,2,3) );
                          ^
    $ ./a.out 
    3
    > sorry, I edited it a little when I posted so I accidentally left out.
    Yeah, and that's what bugs us when you do.
    We've seen it endless times where people attempt to be brief, and only succeed in snipping out what was vital to the problem.


    One more thing
    Code:
        for ( int i = 0;  i < Size; i++ ){
          uint32_t data;
          if (i == 0){
            data = SPI.transfer(0xff);
            if (Size == 1){ return data; }
          }
          else{
            data |= (uint32_t)SPI.transfer(0xff) << (8 * i);
            }
          return data;
        }
    Is that return data mis-placed?
    Because as written, your for loop runs exactly once.

    It's also massively convoluted.

    This does the same thing with no special cases.
    Code:
        uint32_t data = 0;
        for ( int i = 0;  i < Size; i++ ){
            data |= (uint32_t)SPI.transfer(0xff) << (8 * i);
        }
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. End of a variable argument list
    By GigaRoid in forum C++ Programming
    Replies: 38
    Last Post: 09-03-2011, 05:37 PM
  2. Variable Argument functions
    By dnysveen in forum C++ Programming
    Replies: 13
    Last Post: 06-01-2006, 06:03 PM
  3. variable argument lists
    By cProGrammer28 in forum C Programming
    Replies: 2
    Last Post: 05-03-2005, 06:27 AM
  4. Variable argument functions
    By quantum in forum C Programming
    Replies: 3
    Last Post: 12-19-2003, 10:52 AM
  5. I'll have a Variable argument list to go...
    By SMurf in forum C Programming
    Replies: 6
    Last Post: 02-27-2003, 02:02 PM

Tags for this Thread