Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Passing a variadic function to a variadic function via a pointer

I’m kinda confused with the usage of <stdarg.h> features. I can’t figure out how to properly pass a va_list to the argument function. Here’s a simplified example of what I’m trying to achive:

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

void caller(int (*func)(size_t, ...), size_t n_args, ...) {
    va_list args;
    va_start(args, n_args);
    va_list args_for_func;
    va_copy(args_for_func, args);
    printf("(");
    for (size_t i = 0; i < n_args-1; i++) {
        printf("%i, ", va_arg(args, int));
    }
    printf("%i) => ", va_arg(args, int));
    int result = func(n_args, args_for_func);
    va_end(args_for_func);
    printf("%i", result);
    va_end(args);
}

int sum(size_t n_args, ...) {
    va_list args;
    va_start(args, n_args);
    int result = 0;
    for (size_t i = 0; i < n_args; i++) {
        result += va_arg(args, int);
    }
    va_end(args);
    return result;
}

int main() {
    // expected: (1, 2, 3, 4, 5) => 15
    // got: (1, 2, 3, 4, 5) => gibberish
    caller(sum, 5llu, 1, 2, 3, 4, 5);
}

>Solution :

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

A function can only process its variadic parameters using a va_list, and the parameters referenced by the va_list cannot be expanded out in a call to another variadic function. However, the va_list value can be passed by value to another function, so the way to solve the problem is to change the function pointer to point to a function that uses a va_list:

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

void caller(int (*func)(size_t, va_list), size_t n_args, ...) {
    va_list args;
    va_start(args, n_args);
    va_list args_for_func;
    va_copy(args_for_func, args);
    printf("(");
    for (size_t i = 0; i < n_args-1; i++) {
        printf("%i, ", va_arg(args, int));
    }
    printf("%i) => ", va_arg(args, int));
    int result = func(n_args, args_for_func);
    va_end(args_for_func);
    printf("%i", result);
    va_end(args);
}

int vsum(size_t n_args, va_list args) {
    int result = 0;
    for (size_t i = 0; i < n_args; i++) {
        result += va_arg(args, int);
    }
    return result;
}

int sum(size_t n_args, ...) {
    va_list args;
    va_start(args, n_args);
    int result = vsum(n_args, args);
    va_end(args);
    return result;
}

int main() {
    caller(vsum, 5llu, 1, 2, 3, 4, 5);
}
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading