Errors/Debugging

From SC2Mapster Wiki
Jump to: navigation, search

Errors

When using custom script extensively it is only a matter of time before an on-save compile error will be encountered. Reasons for an error can range from typing mistakes to some rather tricky language quirks. Since script errors render a map un-playable it is important to understand them so that they can be resolved quickly and painlessly.

Can only pass basic types

Galaxy does not allow for complex types to be used as function arguments. Such types are based on structs and arrays.

struct forward declaration not supported

Galaxy does not support separating the declaration and definition of structs. The presence of this error hints of a purposeful design decision to not support the feature.

Example

Using a forward declaration of a struct so that it can be used before being defined will generate this error.

struct foo; // error : "struct forward declaration not supported"
foo pre_foo;
struct foo{
    int bar;
};
foo post_foo;

There is no way to achieve this desired behavior in Galaxy.

A workaround is to define structs at the same time they are declared. This unfortunately has a negative impact on the readability of your script header.

struct foo{
    int bar;
};
foo pre_foo;
foo post_foo;

Syntax error

  • You are using a function that is forward defined:
void func () { forwardDefinition(); }
void forwardDefinition() { }
Solution 1: Put the function before
void forwardDefinition() { }
void func () { forwardDefinition(); }
Solution 2: Put the function prototype before
void forwardDefinition(); // Prototype
void func () { forwardDefinition(); }
void forwardDefinition() { }
  • Variable declarations must be made at the top of the function.
void func() {
 ::::int a;
 ::::a = 1;
 ::::int b; // Must be moved right after int a;

Internal compiler error

The Galaxy compiler will throw an internal error when a non-parsing related error is encountered. This is usually the result of heavily deformed script that is outside the average use of the compiler.

Example: Maximum parse unit length

A single parsed unit cannot be more than 2046 characters in length. Any number of parsed units can be on the same line as long as each individually is less than 2046 characters. The error is likely due to a buffer overflow of a 2048 character long buffer during the parsing process.

//Error Below : Internal compiler error
//01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234

Shortening the unit length will resolve the error. It is recommended to avoid such overly long units in well written code as shorter units are generally more readable.

Incorrect Type (Implicit cast not allowed)

Galaxy is a type safe language so only allows expressions of the same type as declared by variable type during assignment or parameter type for an argument. To improve usability some types support implicit casting in this case (eg byte and int) however most types do not allow for implicit casts to occur. Trying to preform such an illegal implicit cast will result in this error.

Example: Incorrect Assignment

When changing a type of a variable it is easy to forget to change its assignments to reflect the type change. For example a string variable might have been changed to an int variable while forgetting to change a null assignment to a valid int type. Such an example can also occur if the programmer is unsure of what type an expression can be used as.

int icnaint = null; // ERROR : Incorrect Type (Implicit cast not allowed)

The solution is to make sure that only the corresponding types are used for the assignment.

int icnaint = 0; // 0 is a similar to null for int.

Parameter type does not match the function definition

  • You are trying to call a function with an argument of the wrong type.
void takeInt(int a) {}
takeInt(false); // Error!

Wrong number of parameters

  • You are trying to call a function with the wrong number of parameters.
void takeOne(int a) {}
takeOne(1, 2); // Error!

Function not found

  • If the entry point void MapInit(); is not defined.

Bulk copy not supported

Galaxy does not support implicit copying of types larger than a single word (int). The number of declared members in a struct is irrelevant as long as the size of the struct type remains 1 word or less. Struct types themselves are byte aligned when used inside a struct. This can also be applied to arrays.

It is worth noting that this does not apply to function arguments. Galaxy does not permit function arguments of a complex type even if that type allows for implicit copying. Complex types can only be passed by reference.

Example

Trying to implicit bulk copy an array consisting of 5 bytes is not allowed.

typedef byte[5] bulk_t;
bulk_t bulka;
bulk_t bulkb = bulka; // Error : Bulk copy not supported

Reducing array size to 4 bytes or less allows for the occurrence of implicit bulk copy.

typedef byte[4] bulk_t;
bulk_t bulka;
bulk_t bulkb = bulka;

If shortening type length is not possible then a bulk copy function can be written and called. This function explicitly copies every element of data from a reference of a type to another reference of the same type. To pass a struct or array type as a function parameter consider using a reference instead of the bulk copy as it becomes very expensive for large types.

typedef byte[5] bulk_t;
void bulk_t_bulkcopy(arrayref<bulk_t> to, arrayref<bulk_t> from){
    int i;
    for( i = 0 ; i < 5 ; i+= 1 ){
        to[i] = from[i];
    }
}
bulk_t bulka;
bulk_t bulkb;
// Called at map initialization.
void bulk_t_init(){
    bulk_t_bulkcopy(bulkb, bulka);
}

Could not allocate Global Memory (try reducing the size)

The Galaxy virtual machine is based on the Harvard architecture meaning that it has separate heaps for code and global variables. Due to the limitations of the virtual machine instruction address field, each heap is limited to at most 16,777,216 bytes (16 Megabytes) of memory. Trying to allocate global variables that cannot fit inside this heap limit will produce this error.

This error should never be encountered as long as global allocation remains reasonable. To put it in perspective it is larger than many 16 bit games from the early 1990s which included art assets. It can be encountered in GUI by excessive sized array allocation.

The maximum heap size used to be only 2,097,152 bytes (2 Megabytes) but was raised considerably by a patch.

Example: Big Array

Trying to allocate an unreasonably sized array will produce this error.

int[4194304] gdatlarray; // ERROR : Could not allocate Global Memory (try reducing the size)

The only solution is to re-design your script to not require such large amounts of global memory. If you are not using the full range of the int type it is possible to save significant memory by using the byte type instead to shorten the length of each element.

failed: 32k - 1 size limit to local variables

  • You are trying to use too much memory with your local variables.
void f() { int[1000000] a; }

Invalid address

  • You are trying to call a function in the global declarations.
int giveone() { return 1; }
const int test = giveone();

Nested iteration detected

  • You are using two "Pick Each __" actions, one within the other.
  • To avoid this replace one of the actions with a "For Each _" action.

Registry overflow

The Galaxy compiler cannot deal with a sequence involving operations on more than 28 object references at once. The error is possibly related to parsing all required objects to compile a statement.

It is important to note that no line number is provided for the cause of this error. To track down the error look at all very long statements which were recently modified. If necessary disable sections of code to narrow down the cause of the error.

Example

Trying to in-line sum 29 complex objects such as points, strings or text will produce the error.

typedef point roobject_t;  // Applies to points.
//typedef string roobject_t; // And strings.
//typedef text roobject_t;   // And text.
roobject_t rop = null;
//Error Cause Below : Registry overflow
roobject_t roo = rop + rop + rop + rop + rop + rop + rop + rop + rop + rop + rop + rop + rop + rop + rop + rop + rop + rop + rop + rop + rop + rop + rop + rop + rop + rop + rop + rop + rop;

The solution is to fragment the statement into several statements involving fewer complex objects.

typedef point roobject_t;  // Applies to points.
//typedef string roobject_t; // And strings.
//typedef text roobject_t;   // And text.
roobject_t rop = null;
roobject_t rop7 = rop + rop + rop + rop + rop + rop + rop;
roobject_t roo = rop7 + rop7 + rop7 + rop7 + rop; // Sum of 29 objects.

Most statements involve operators on only a few complex objects. As a result this error is unlikely to be encountered during normal scripting activities. It can also occur in GUI if concatenating more than 28 string or text objects in a single action.

Error List