Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>I've run into the same problem. As far as I could tell, this seems to be the case:</p> <p><strong>Every single static and global variable of class type will silently fail to be initialized if even a single class attempts dynamic allocation at any point during its initialization.</strong> Presumably this is because the ByteBuffer being used for dynamic memory isn't yet available. I wish Alchemy would be more clear with its error messages, because at the moment it's like a strand of old-timey Christmas lights where one dead bulb would cause the entire strand to shut off.</p> <p>For a workaround, once you've discovered the offending object, you'll need to somehow defer its initialization to runtime. The three techniques that come to mind are pointers, lazy evaluation functions, or references to buffers initialized with placement new.</p> <p><b>Pointers</b></p> <pre><code>// `global` is now a pointer TestClass *global; // all global variable initialization is found here now void init_globals() { global = new TestClass("global"); } int main(int argc, char **argv) { // this needs to be explicitly called at the start Alchemy init_globals(); </code></pre> <p>You'll then need to refactor your code, changing every occurence of <code>global</code> to <code>(*global)</code>.</p> <p><b>Function</b></p> <pre><code>// `global` is now a function TestClass&amp; global() { // static locals are initialized when their functions are first called static TestClass global_("global"); return global_; } </code></pre> <p>Now you need to replace every occurence of <code>global</code> with <code>global()</code>. Notably, this is the only one of these three techniques that doesn't require an explicit <code>init_globals</code> call. I recommend this way unless the name changing to <code>global()</code> is troublesome for some reason... in which case:</p> <p><b>Placement new</b></p> <pre><code>// a memory buffer is created large enough to hold a TestClass object unsigned char global_mem[sizeof(TestClass)]; // `global` is now a reference. TestClass&amp; global = *(TestClass*)(void*)global_mem; void init_globals() { // this initializes a new TestClass object inside our memory buffer new (global_mem) TestClass("global"); } int main(int argc, char **argv) { init_globals(); </code></pre> <p>The advantage of this approach is you don't need to change any other code, as <code>global</code> is still just called <code>global</code>. Unfortunately, maintaining an <code>init_globals</code> function can be troublesome.</p> <hr /> <p><b>Edit:</b><br/> As discovered in a later question, in addition to dynamic allocation, functions containing static locals also cannot be called during Alchemy's initialization.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload