• New Horizons on Maelstrom
    Maelstrom New Horizons


    Visit our website www.piratehorizons.com to quickly find download links for the newest versions of our New Horizons mods Beyond New Horizons and Maelstrom New Horizons!

Discussion What's the deal with array sizes of 1 throwing a runtime error?

Kahenraz

Landlubber
While testing out various data types available in the engine's scripting language I found an odd quirk. You can't have an array of size 1.

An array of size 2 is fine:

Code:
int list[2];

list[0] = 123;

But an array of size 1 will error on assignment:

Code:
int list[1];

list[0] = 123; // error.log: function 'ExecuteConsole' stack error

Is this just one of many quirks or is there some logic to this?

It's actually possible to work around this by shrinking the array after its creation:

Code:
int list[2];

SetArraySize(&list, 1);

list[0] = 123;

trace("array size : " + GetArraySize(&list));
trace("list[0]    : " + list[0]);
 
Last edited:
I've decided that this is just a quirk of the language and probably a bug. Creating an array of size 1 seems to create a non-array variable:

Code:
int list[1];
list = 123;

trace(list); // Outputs 123

Here's what tipped me off:

Code:
int list[1];

trace(GetArraySize(&list)); // error.log: Not array

A more useful error will appear if a #define is used instead of a literal number. This is also interesting because this suggests that a #define is more than a simple find/replace pre-processor:

Code:
#define ARRAY_SIZE 1;

int list[ARRAY_SIZE]; // error.log: Invalid array (list) size

It's also horrifying given that an array size of 1 specified by a #define would cause an unexpected runtime issue like this. At least there is a useful error for it to fall back on.
 
@Kahenraz: Are you active on Discord as well?
A lot of the C++ experts are actively working there on the newer version of the Storm engine.
Of them all, @Hammie, @kb31 and @cooodesloth are generally active on the forum here.
But most of the others are only on the Discord side...
 
This is what the current C++ source code looks like for the To Each His Own version of the Storm Engine:
Code:
void DATA::SetType(S_TOKEN_TYPE _element_type, uint32_t array_size)
{
    ClearType();
    Data_type = _element_type;
    bArray = false;

    if (array_size > 1)
    {
        bArray = true;
        ArrayPTR.clear();
        Number_of_elements = array_size;
        ArrayPTR.reserve(Number_of_elements);
        for (uint32_t n = 0; n < Number_of_elements; n++)
        {
            ArrayPTR.emplace_back(_element_type);
            ArrayPTR.back().SetVCompiler(pVCompiler);
        }
    }
    else
    {
        ArrayPTR.clear();
        Number_of_elements = 1;
    }
}

Which confirms your conclusion that the 'array_size' is used to drive the distinction between arrays and non-arrays.

Might be different from how it works in POTC, but I doubt this has changed since.

I'm trying to refactor some of the scripting code and make the compiler available as a separate library, but it's going to take a lot of effort to clean up.
 
Back
Top