Using asprintf() on windows

asprintf, c, windows

Solution

The `asprintf()` function is not part of the C language and it is not available on all platforms. The fact that Linux has it is unusual.

You can write your own using `_vscprintf` and `_vsprintf_s`.

int vasprintf(char **strp, const char *fmt, va_list ap) {
    // _vscprintf tells you how big the buffer needs to be
    int len = _vscprintf(fmt, ap);
    if (len == -1) {
        return -1;
    }
    size_t size = (size_t)len + 1;
    char *str = malloc(size);
    if (!str) {
        return -1;
    }
    // _vsprintf_s is the "secure" version of vsprintf
    int r = _vsprintf_s(str, len + 1, fmt, ap);
    if (r == -1) {
        free(str);
        return -1;
    }
    *strp = str;
    return r;
}

This is from memory but it should be very close to how you would write `vasprintf` for the Visual Studio runtime.

The use of `_vscprintf` and `_vsprintf_s` are oddities unique to the Microsoft C runtime, you wouldn't write the code this way on Linux or OS X. The `_s` versions in particular, while standardized, in practice are not often encountered outside the Microsoft ecosystem, and `_vscprintf` doesn't even exist elsewhere.

Of course, `asprintf` is just a wrapper around `vasprintf`:

int asprintf(char **strp, const char *fmt, ...) {
    va_list ap;
    va_start(ap, fmt);
    int r = vasprintf(strp, fmt, ap);
    va_end(ap);
    return r;
}

This is not a "portable" way to write `asprintf`, but if your only goal is to support Linux + Darwin + Windows, then this is the best way to do that.

Problem

I have written a C program which works perfectly on linux, but when I compile it on windows, it gives me an error saying that asprintf() is undefined. It should be a part of the stdio library but it seems that many compilers do not include it. Which compiler can I use for windows which will allow me to use the asprintf() function? I have tried multiple compilers and none seem to define it so far.

Original source