boot2

Playing with the boostrap
git clone https://git.ryansepassi.com/git/boot2.git
Log | Files | Refs | README

116-struct-ret-vararg.c (1463B)


      1 /* Struct return from a variadic function.
      2  *
      3  * Combines two ABI-shaped concerns: the variadic save area (cg.scm
      4  * around L1027 has a TODO for variadic args >= 4) and the struct
      5  * return slot (a single 8-byte slot).
      6  *
      7  * If the hidden return pointer is wired through arg0, the variadic
      8  * save area's indexing must skip it; if it isn't wired, a 2-word
      9  * struct return will silently truncate. Either way this surfaces
     10  * the interaction. */
     11 
     12 #ifndef CCSCM
     13 #include <stdarg.h>
     14 #else
     15 typedef char *va_list;
     16 #define va_start(ap, n) __builtin_va_start(ap, n)
     17 #define va_arg(ap, t)   __builtin_va_arg(ap, t)
     18 #define va_end(ap)      __builtin_va_end(ap)
     19 #endif
     20 
     21 struct Pair { long a; long b; };
     22 
     23 struct Pair sum_pair(int n, ...) {
     24     va_list ap;
     25     long total_a = 0;
     26     long total_b = 0;
     27     int i = 0;
     28     va_start(ap, n);
     29     while (i < n) {
     30         total_a = total_a + va_arg(ap, int);
     31         total_b = total_b + va_arg(ap, int) * 10;
     32         i = i + 1;
     33     }
     34     va_end(ap);
     35     struct Pair r;
     36     r.a = total_a;
     37     r.b = total_b;
     38     return r;
     39 }
     40 
     41 int main(int argc, char **argv) {
     42     /* Two pairs of (int,int): (1,2) (3,4) -> a = 1+3 = 4, b = (2+4)*10 = 60 */
     43     struct Pair r = sum_pair(2, 1, 2, 3, 4);
     44     if (r.a != 4)  return 1;
     45     if (r.b != 60) return 2;
     46 
     47     /* Three pairs: (10,1) (20,2) (30,3) -> a = 60, b = 60 */
     48     struct Pair s = sum_pair(3, 10, 1, 20, 2, 30, 3);
     49     if (s.a != 60) return 3;
     50     if (s.b != 60) return 4;
     51     return 0;
     52 }