Compile time object contruction in C++

Suppose that I have an object like a “command”, which gets put together into a linked list, with each “object” containing a text string, a function pointer to the action routine for that command, and a pointer to the next command.

Then in C++, I can sprinkle these around my source code as appropriate a global objects, and the constructor can link them all together.

class cmd_t {
private:
    static cmd_t *head;
    const char *text;
    void *(*func)(char *);
    cmd_t *next;

public:
    cmd_t(const char *t, void*(*f)(char *)) {
    text = t;
    func = f;
    if (head == NULL) {
        head = this;
    } else {
        cmd_t *p = head;
        while (p->next != NULL) {
        p = p->next;
        }
        p->next = this;
    }
    }
}

cmd_t add("add", add_f);
cmd_t sub("sub", sub_f);
cmd_t mul("mul", mul_f);

Now, that’s all stuff that COULD happen at compile time, I think. But it doesn’t, even with “-Os -flto”

Is there any way to convince the gnu C++ compiler to MAKE it happen at compile time? Extra credit if things can be “const” enough to end up in flash on a microcontroller.

(I tried adding some const and static qualifiers in essentially random places, which resulted in behaviors ranging from “no change” to “compile errors.”

(full compileable source attached.)

parser.cpp (858 Bytes)

Extra credit if things can be "const" enough to end up in flash on a microcontroller.

How can they? Objects are created at run-time, not at compile time.

It's always a good idea to typedef function pointer.

class cmd_t {
  private:
    static cmd_t *head;
    static int a;
    const char *text;
    cmd_t *next;
    typedef void* (*func)(const char*);
    func funcptr;
  public:
    cmd_t(const char *t, func newfunc)
    {
      text = t;
      funcptr = newfunc;

      if (head == NULL)
      {
        head = this;
      }
      else
      {
        cmd_t *p = head;
        while (p->next != NULL) 
        {
          p = p->next;
        }
        p->next = this;
      }
    }
};

 cmd_t* cmd_t::head = nullptr;

void* add_func(const char*)
{
  return nullptr;
}

cmd_t add("add", add_func);

void setup() {
  // put your setup code here, to run once:

}

void loop() {
  // put your main code here, to run repeatedly:

}

Objects are created at run-time, not at compile time.

Static and global objects are "created" at compile time, just not constructed. But I don't see why some types of construction COULD happen at compile time...

What about using initializers?
That can do some initialization at compile time, but it may not help in this case since you are doing some list linking using objects outside of the object being constructed.

i.e. instead of this:

cmd_t(const char *t, void*(*f)(char *)) {
    text = t;
    func = f;

Do this:

cmd_t(const char *t, void*(*f)(char *)) : text(t), func(f) {

Watch out! You have no control in the order that things are created in "compile time". Not really compile time but before setup(), where things start getting ordered by you.

-jim lee

You have no control in the order that things are created in "compile time".
Not really compile time but before setup(), where things start getting ordered by you.

I think I can live with that...