C++ – Can a Compiler Instantiate Objects at Compile Time?

ccompilationcompileroptimization

I am writing some code that has a very large number of reasonably simple objects and I would like them the be created at compile time. I would think that a compiler would be able to do this, but I have not been able to figure out how.

In C I could do the the following:

#include <stdio.h>

typedef struct data_s {
    int a;
    int b;
    char *c;
} info;

info list[] = {
    1, 2, "a",
    3, 4, "b",
};

main()
{
   int i;
   for (i = 0; i < sizeof(list)/sizeof(*list); i++) {
     printf("%d %s\n", i, list[i].c);
   }
}

Using #C++* each object has it constructor called rather than just being layed out in memory.

#include <iostream>
using std::cout;
using std::endl;

class Info {
    const int a;
    const int b;
    const char *c;
public:
    Info(const int, const int, const char *);
    const int get_a() { return a; };
    const int get_b() { return b; };
    const char *get_c() const { return c; };
};

Info::Info(const int a, const int b, const char *c) : a(a), b(b), c(c) {};

Info list[] = {
    Info(1, 2, "a"),
    Info(3, 4, "b"),
};

main()
{
    for (int i = 0; i < sizeof(list)/sizeof(*list); i++) {
        cout << i << " " << list[i].get_c() << endl;
    }
}

I just don't see what information is not available for the compiler to completely instantiate these objects at compile time, so I assume I am missing something.

Best Answer

In C++11 you can use a constexpr constructor like this:

class Info {
    const int a;
    const int b;
    const char *c;
public:
    constexpr Info(const int, const int, const char *);
    const int get_a() { return a; }
    const int get_b() { return b; }
    const char *get_c() const { return c; }
};

constexpr Info::Info(const int a, const int b, const char *c) : a(a), b(b), c(c) {}

constexpr Info list[] = {
    Info(1, 2, "a"),
    Info(3, 4, "b"),
};

GCC 4.7.1 in C++0x mode supports constexpr constructors at compile time, and the above code works as desired, with no calls to the Info constructor in the generated code.

Note that the compiler is not required to do full construction at compile time - in principle it could defer the construction to runtime.