Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

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.

share|improve this question
1  
Of course they get the constructors called, because you explicitly call them. What's wrong with using the same method as the C version? By the way, this question belongs on StackOverflow. –  Mr Lister Sep 16 '12 at 5:55
1  
He can't use the same method as the C version because the class has a constructor and because the class has private data members. Either one makes the class non-POD. –  David Hammen Sep 16 '12 at 11:49
    
Ehm, but with "the same method as the C version" I meant doing it the same way as the C version... –  Mr Lister Sep 16 '12 at 19:44

6 Answers 6

up vote 4 down vote accepted

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.

share|improve this answer

If you want all that extra stuff in there, fine - you'll have to instantiate them explicitly.

But there's nothing stopping you using the C way for your objects, just make and treat them as POC structs. C++ is that backwardly compatible. Alternatively, place a struct inside your class as a member variable and instantiate that.

With C++11 you can use initializer lists to construct your object, as per this SO answer

share|improve this answer
    
Except it won't work. He has const data members in that class, those members are private, and the class has a non-default constructor. The class is not aggregate, so he can't use an initializer list for it. Not even in C++11. –  David Hammen Sep 16 '12 at 16:35

You're hosed. The problems are those const private data members and the constructor. These makes your class a non-aggregate class. The only way to construct an Info object is by calling the constructor, and the compiler doesn't do that.

share|improve this answer

Who says the compiler isn't doing exactly what you want? In the code shown, a compliant compiler may compile your List code to the same assembly as the C code.

share|improve this answer
    
Using GDB I can see the constructors being called. –  gam3 Sep 17 '12 at 14:32
    
Try compiling release with optimizations on. Debugging debug code of course will step into the constructor. Any other debugger would be crap. –  Thomas Eding Sep 17 '12 at 17:46

This probably isn't going to help you very much, but I'd suggest that you look into template meta programming. :-)

share|improve this answer

You can't really create them at compile time, but you can trick the compiler into specifying the creation of pretty complex data structures by using macros to store information, and then using multiple different definitions of the macro to deposit information as needed.

For example, you can have a macro structure like

in a header file "header.h":

foo(x,1) 
foo(y,2)

then in one place

#define foo(a,b) a = b;
#include "header.h"
#undef foo

and in another place

#define foo(a,b) #a,

char *name = {
#include "header.h"
};
#undef foo

and so on

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.