Best Way to Collect Initialization Actions using C++ Capabilities?

I'm writing a scripting language with additional functions that can be built in.

The built-in functions would be written in C++ for speed.

In different builds of the scripting language, some functions might be omitted.

So, I'm looking for the best way to automatically collect, at compile time or early at execution time, the full list of extra built-in functions, so that the script interpreter can parse and execute a script (to do this, it has to know about any additional capability compiled in).

For example, in Visual C++, I'd like to simply add a source file containing built-in scripting language functions, and have the script interpreter know they are there.

My goal would be no additional configuration actions other than adding the source file to the project (in other words, no need to modify other files). The software should somehow figure out that additional script built-in function capability is in the build.

Google Test seems to do this somehow with a macro like TEST_F, but I'm not sure how this works under the hood. The list of tests is somehow collected automatically at compile time or early at run time.

To give some practical background ... decades ago I did some work extending the Tcl scripting language. It was only necessary somehow in initialization to call a command to "register" a new function available to the script interpreter, but the source code had to be modified manually to include the additional initialization. The manual modification is what I'm trying to avoid.

Is there a standard design pattern for this in C++?

reddit.com
u/DaveInTheMidwest — 4 days ago

Question About Copy Constructor for Class with Members that Need Deep Copy

I have a class (m_buf in the code below is of this class type) that appears as a data member in another class for which I'm writing the copy constructor.

The underlying class (m_buf in the code below is of this class type) uses dynamic allocation and needs a deep copy.

According to Google, this form of the copy constructor would result in the copy constructor (rather than the copy assignment operator) for m_buf being called.

LgFbufUint8::LgFbufUint8(const LgFbufUint8& fbuf) : m_state{fbuf.m_state},
                                                    m_errs{fbuf.m_errs},
                                                    m_fname{fbuf.m_fname},
                                                    m_buf{fbuf.m_buf}
{
   //According to Google search, if the member initializer list is used (as it
   //is above), the copy constructor (rather than the copy assignment operator)
   //will be called. Because of the required non-shallow copy of m_fname and
   //m_buf, this is the desired behavior.
}

My initial guess was this form:

LgFbufUint8::LgFbufUint8(const LgFbufUint8& fbuf)
{
   m_state = fbuf.m_state;
   m_errs  = fbuf.m_errs;
       //Shallow copy ok for two members above.
   m_fname = fbuf.m_name;  //std::string
   m_buf   = fbuf.m_buf;   //Handwritten, with dynamic allocation.
       //Deep copy required for two above.
}

But I suspect that second form would call the assignment operator rather than the copy constructor for m_name and m_buf.

Question: Did I get that right? The first form would call the copy constructors for m_name and m_buf, but the second form would call the assignment operators?

Bonus Question: Using the second form, is there any way to call the copy constructors rather than the assignment operators. (Not that I'd want to do this, but just curious.)

reddit.com
u/DaveInTheMidwest — 4 days ago

This morning I was carrying my full coffee mug to the living room and, with no warning, the mug fractured and dumped my entire load of coffee on the carpet.

There was no impact to the mug. I was simply walking with the mug.

The fracture was clean, and there seem to be only two pieces of the mug.

I've never seen anything like this happen before.

u/DaveInTheMidwest — 4 months ago