Compound literals in MSVC

The construct (Type){initialisers} is not a cast operation, but it is the syntactic construct of a compound literal. This is a C99 construct, which GCC also supports in its C++ compiler as an extension. As far as I can determine, compound literals are not supported up to and including MSVC 2012, in either its C or C++ mode. The support in C mode was introduced later, in MSVC 2013. In C++ mode it is still not supported and I believe it is unlikely support will be added.

For MSVC 2012 and older, the alternatives for this construct are

  • Explicitly declare and initialise a temporary object of the desired struct type and use that instead of the compound literal in the assignment
  • Instead of doing a single assignment with the compound literal, use a separate assignment for each individual member.

MSVC is not conformant to C99 and only loosely conformant to previous versions of the C standard. I know no way to do what you want syntactically with MSVC, but the same effect can be obtained by using static const structs instead of anonymous compound literal constants, and local struct variables that are initialized with the correct values instead of anonymous compound literals that are nonconstant.

The idea behind this approach is that a C99 compound literal is (at least nearly) equivalent to a local variable of the same type at the same scope, initialized with the contents of the braces. Using static const structs in the case where the data is constant is just an optimization (it will likely produce smaller/faster code than the C99 compound literal approach).


Visual Studio, since VS2013, supports Compound literals and Designated initializers. Which C99 features are available in the MS Visual Studio compiler?

Example:

// main.c
#include <stdio.h>

void func(int(*array)[3]);

int main()
{
    // Designated initializers

    int a[6] = { [4] = 29, [2] = 15 }; // [0, 0, 15, 0, 29, 0]

    struct point { int x, y; };
    struct point p = { .y = 13, .x = 27 }; // x = 27, y = 13

    union foo { int i; double d; };
    union foo f = { .d = 4 }; // d = 4.0

    struct point ptarray[5] = { [2].y = 34, [2].x = 42, [0].x = 58 };
    // (58 0), (0 0), (42 34), (0 0), (0 0)

    // Compound literals

    int *a1 = NULL;
    a1 = (int[6]) { [4] = 29, [2] = 15 }; // [0, 0, 15, 0, 29, 0]

    struct point p1;
    p1 = (struct point) { .y = 13, .x = 27 }; // x = 27, y = 13

    union foo f1;
    f1 = (union foo) { .d = 4 }; // d = 4.0

    struct point *ptarray1 = NULL;
    ptarray1 = (struct point[5]) { [2].y = 34, [2].x = 42, [0].x = 58 };
    // (58 0), (0 0), (42 34), (0 0), (0 0)

    int *p2 = NULL;
    p2 = (int[2]) { -1 };
    p2 = (int[]) { -73, 89, 92 };
    func(&(int[]) { -73, 89, 92 });

    return 0;
}

void func(int(*array)[3])
{
    for (int i = 0; i < 3; i++) {
        printf("%d ", (*array)[i]);
    }
}