Search code examples
cvariadic-functionsellipsis

Weird behaving ellipsis function (va_list)


The following max function is supposed to return 5 but it returns 4294967294 instead. I suspect the weird behavior arise from casting variables but couldn't figure it out. Can someone detect the fault?

System: Windows 7 (64 bits), mingw64

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

int64_t max(int64_t n, ...) {
    va_list v;
    int64_t i, t, max = INT64_MIN;

    va_start(v, n);

    for (i = 0; i < n; i++) {
        t = va_arg(v, int64_t);

        if (max < t) {
            max = t;
        }
    }

    va_end(v);
    return (max);
}

int main(int argc, char **argv) {
    printf("max(3, 1, 5, -2)   : %3I64d\n", max(3, 1, 5, -2));
    return (0);
}

Solution

  • The compiler doesn't know that 1,5 and -2 are supposed to be type int64_t. So it will treat them as normal ints and will only use that much space on the stack for them.

    You then read them as int64_t which is certainly larger than int and so your input and your var_args are out of alignment.

    One way to fix, cast to int64_t at the call site.

    printf("max(3, 1, 5, -2)   : %"PRId64"\n", max(3, (int64_t)1, (int64_t)5, (int64_t)-2));
    

    You could also obviously explicitly pass int64_t typed variables.