Can I coerce C++ construction of objects to happen at compile time, even for relatively complex objects?
In particular, suppose I want to build a linked list of keywords:keyword *listhead = NULL;
keyword _if(listhead, "if", process_if);keyword _else(listhead, "else", process_else);keyword _while(listhead, "while", process_while);
And I have constructor/object code that looks somewhat like:class keyword {
public:
const char *text;
void (*func)(char *);
keyword *next;
keyword(keyword *&head, const char *t, void(*f)(char *)) {
text = t;
func = f;
next = head;
head = this; // add to beginning of linked list
}
};
In theory, that could all happen at compile time, leaving me with a linked list that could theoretically be "const" and stuck in ROM instead of precious RAM.
Is there a way to make this happen?
if there is no need to add elements dynamically, just make it an array instead of a list.
Well, you can declare an array and still interlink the elements in order to make it conform to list interface
Using the current class declaration
class keyword {
public:
const char *text;
void (*func)(char *);
keyword *next;
keyword(keyword *&head, const char *t, void(*f)(char *)) {
text = t;
func = f;
next = head;
head = this; // add to beginning of linked list
}
};
keyword *listhead = nullptr;
keyword keywords[] = { { listhead, "if", process_if }, { listhead, "else", process_else }, { listhead, "while", process_while } };
Sequencing rules guarantee that array elements are constructed left-to-right.
Or you can use a POD-class instead and do this
class keyword {
public:
const char *text;
void (*func)(char *);
keyword *next;
};
keyword keywords[] = { { "if", process_if, nullptr }, { "else", process_else, &keywords[0] }, { "while", process_while, &keywords[1] } };
keyword *listhead = &keywords[2];
This feels even more "compile-timeish" although in reality both variants are virtually the same.
keyword keywords[] = { { "if", process_if, nullptr }, { "else", process_else, &keywords[0] }, { "while", process_while, &keywords[1] } };
What was clear from my original message (especially after the forum software mangled my newlines) was that I want to AVOID having a single declaration of a big keyword table. I want to intersperse the keyword definitions with the code that implements each keyword like:
keyword _if(listhead, "if", process_if);
void process_if() {
// code to process if
}
keyword _else(listhead, "else", process_else);void process_else() {
// code to process else
}
This makes it easy to add keywords, or leave them out vs conditional compilation, and would make for a cleaner-looking source code (although harder to look at and see which commands are implemented.)
C++ run-time constructors would do this just fine, and they build a data structure that is essentially complete and static that COULD have been built at compile-time.
just make it an array instead of a list.
I could settle for that, if there is a way to initialize individual elements of an array at different points of the source code...
(I'm pretty sure I could also do this with inline assembly, since assembly macros tend to be much more powerful than C macros. But... eww.)