Compiler Error Messages
Introduction
This is a list of some reasons why the compiler will produce certain error messages. It does not cover all possible error messages, nor does it identify every possible cause for each of the messages discussed.
When the compiler outputs an error message, it will include the line number in the script where the error was detected. Sometimes the code mistake that is causing the message is actually located on the line preceding the one identified in the message. The location of the mistake is most likely on the identified line or the preceding line. It is rare that the mistake is elsewhere in the script but it can happen, particularly when the mistake involves the curly braces '{' or '}' which are used to group several code statements into sections called code-blocks. When a code statement spans several lines and the mistake was actually made in the previous code statement, the line displayed in the error message could also be a few lines off. The compiler will never spit out an error identifying some line when the actual mistake is located on a line past the line number shown in the error message. The code mistake will always be either on the identified line or somewhere before it.
Error Messages
Note this list is incomplete. Some error messages are not covered in this guide.
Summaries
Error Message and Meaning | Examples | |||
---|---|---|---|---|
|
// Incorrect: string sMsg = "The number of months in a year is " +12; The problem is the arithmetic operator "+" is being used in an attempt to add a string-type value with an int-type value. All arithmetic operators require that both operands have the same data type. // Correct: string sMsg = "The number of months in a year is " +IntToString( 12 ); Resolved by converting the int-type value into a string.
|
|||
|
// Incorrect: if( "Some string" != 12 ) return; The problem is the logical comparison operator "!=" is being used in an attempt to test whether a string-type value is not equivalent to an int-type value. All logical operators require that both operands have the same data type. // Correct: if( "Some string" != "12" ) return; Resolved by converting the int-type value into a string.
|
|||
|
// Incorrect: void MyFunction( object oObject ) { const float MY_FLOAT_CONSTANT = 22.0; ... } void main() { const int MY_INT_CONSTANT = 22; ... } The problem is that neither of the two constants MY_FLOAT_CONSTANT and MY_INT_CONSTANT is being defined in the script global scope context. MY_FLOAT_CONSTANT is being defined inside a custom function body, and MY_INT_CONSTANT is being defined inside the main function body. // Correct: const float MY_FLOAT_CONSTANT = 22.0; const int MY_INT_CONSTANT = 22; void MyFunction( object oObject ) { ... } void main() { ... } Resolved by moving the constant definitions outside all function bodies into the script global scope context.
|
|||
|
// Incorrect: void MyCustomFunction( object oCreature, location lLocation ) { ... } void main() { object oPC = GetLastUsedBy(); object oWaypoint = GetNearestObjectByTag( "WaypointTag", oPC ); location lWaypoint = GetLocation( oWaypoint ); MyCustomFunction( lWaypoint, oPC ); MyCustomFunction( oPC, oWaypoint ); } The problem is that the custom function MyCustomFunction is defined at the top to expect two parameters. The first one must be an object data type and the second one must be a location data type. But when the function is called from within the main function body, the parameters being passed in do not match data type wise. In the first call, they are being passed in backwards. The first one passed is a location and the second one an object. In the second call the data type of the second parameter passed is an object but the function expects a location type there. // Correct: void MyCustomFunction( object oCreature, location lLocation ) { ... } void main() { object oPC = GetLastUsedBy(); object oWaypoint = GetNearestObjectByTag( "WaypointTag", oPC ); location lWaypoint = GetLocation( oWaypoint ); MyCustomFunction( oPC, lWaypoint ); MyCustomFunction( oPC, GetLocation( oWaypoint ) ); } Resolved by passing parameters of the correct data type in the order expected.
// Incorrect: void MyCustomFunction( object oCreature, location lLocation ) { ... } void main() { object oPC = GetLastUsedBy(); object oWaypoint = GetNearestObjectByTag( "WaypointTag", oPC ); location lWaypoint = GetLocation( oWaypoint ); MyCustomFunction( OBJECT_INVALID ); MyCustomFunction( oPC, lWaypoint, TRUE ); } The problem is that the custom function MuCustomFunction is defined at the top to expect two parameters. But when the function is called from within the main function body, the wrong number of parameters are being passed in. In the first call, only one parameter is being passed. In the second call three are supplied.
// Correct: void MyCustomFunction( object oCreature, location lLocation ) { ... } void main() { object oPC = GetLastUsedBy(); object oWaypoint = GetNearestObjectByTag( "WaypointTag", oPC ); location lWaypoint = GetLocation( oWaypoint ); MyCustomFunction( OBJECT_INVALID, GetLocation( oPC ) ); MyCustomFunction( oPC, lWaypoint ); } Resolved by passing the correct number of parameters expected by the function.
|
|||
|
// Incorrect: // Some script called "my_script" void MyCustomFunction() { ... } void main() { ... } // Some other script used in or called from an object event. #include "my_script" void main() { ... MyCustomFunction(); ... } The problem is the script "my_script" is being used as an include library by the second script, but "my_script" has a main function defined in it. The compiler includes its contents into the second script when the #include directive is encountered. The result now has two main functions in it, and when the compiler reaches the definition for the main function in the second (master) script, it chokes since it has no idea which version of the main function should be used. // Correct: // Some script called "my_script" void MyCustomFunction() { ... } /* void main() { ... } */ // Some other script used in or called from an object event. #include "my_script" void main() { ... MyCustomFunction(); ... } Resolved by commenting out the main function in the script being included ("my_script" in this example).
|
|||
|
// Incorrect: // Some library script called "my_script" void MyCustomFunction() { ... } // Some other script. #include "my_script" void MyCustomFunction() { ... } void main() { ... MyCustomFunction(); ... } The problem is the library "my_script" is being included by the second script. Both the library and the master script have a definition for the function MyCustomFunction in them. The compiler includes the "my_script" library's contents into the second script when the #include directive is encountered. The result now has two functions called MyCustomFunction defined in it, and when the compiler reaches the second definition for the function in the master script, it chokes since it has no idea which version of the function should be used. // Correct: // Some library script called "my_script" void MyCustomFunction() { ... } // Some other script. #include "my_script" void MyOtherCustomFunction() { ... } void main() { ... MyCustomFunction(); MyOtherCustomFunction(); ... } Resolved by giving one of the two versions of the function a distinct name. Note that when this error is caused by including a library that has a function whose name conflicts with one already defined in the master script, as depicted in this example, it is easiest and safest to rename the one defined in the master script rather than the one in the library which could potentially be used by other scripts elsewhere in the module.
|
|||
|
// Incorrect: // Some script. #included "some_library" void main() { ... } The problem is the keyword #include has been misspelled as #included. // Correct: // Some script. #include "some_library" void main() { ... } Resolved by spelling the keyword correctly as #include. |
|||
|
// Incorrect: // Some script. void main() { int iMy*Bad*Variable = 0; ... } The problem is that asterisk characters are not allowed in an identifier name. Only letters, numbers, and the underscore can be used and identifier names are not allowed to start with a number. // Correct: // Some script. void main() { int iMy_Good_Variable = 0; ... } Resolved by using a variable name that contains only legal characters. // Incorrect: // Some script. int MyFunction( int iX, int iY, int iZ ) { // MyFunction's function body if( iX == 7 ) { iZ = 4; iY = iY +1; return (iY *iZ); return ((iY *iZ) +iX); } // <-- compiler thinks this is the end of the if-statement. string MyOtherFunction( object oPC ) // <-- not in the global scope { ... } The problem is that the first function definition for MyFunction has mismatched curly braces. There are two opening braces but only one closing brace. This means the compiler cannot determine where the end of the function body is. When the next function definition for MyOtherFunction is encountered the compiler thinks you are trying to define a new function within the scope of the MyFunction function body. Functions can only be defined at the global scope level, so it spits out an ERROR PARSING VARIABLE LIST error message. // Correct: // Some script. int MyFunction( int iX, int iY, int iZ ) { // MyFunction's function body if( iX == 7 ) { iZ = 4; iY = iY +1; return (iY *iZ); } // <-- now this curly marks the end of the if-statement. return ((iY *iZ) +iX); } // <-- and this curly marks the end of the function body. string MyOtherFunction( object oPC ) // <-- back in the global scope. { ... } Resolved by inserting a closing curly brace at the right spot to end the if-statement. |
|||
|
// Incorrect: // Some script. ... const int MyVar; const float MyVar; string MyVar; float MyVar; void main() { ... } The problem is the identifier name MyVar is being used to represent a constant integer in one line, then a constant float on the next, a variable string on the third, and a variable float on the fourth. The name can only be used to refer to one thing at a time and must be either constant or variable but not both. // Correct: // Some script. ... const int MY_INT; const float MY_FLOAT; string My_String; float My_Float; void main() { ... } Resolved by giving different identifier names to each different constant and variable being defined. Notice that identifier names are case-sensitive so the names MY_FLOAT and My_Float are treated as different names. Interestingly the following script compiles just fine, although it is certainly not clear at all how valid it is. // Unusual but compiles: // Some script. ... int MyVar1; const int MyVar1 = 1; // < compiles but is MyVar1 variable or constant? string MyVar2; const float MyVar2 = 2.0; void main() { float MyVar3 = MyVar2; // < appears to be OK. // string MyVar4 = MyVar2; // < will generate MISMATCHED_TYPES error } This last script also showcases one good reason why it is not always a very good idea to define variables in the global scope. Something like this could produce a stack error at runtime. |
|||
|
// Incorrect: ... // Prototype for MyFunction void MyFunction( int iNum ); ... // In here MyFunction is available for use. // Implementation for MyFunction void MyFunction( int iNum, object oObject ) { ... } The problem is the prototype line for MyFunction says the function returns nothing, and requires one integer parameter. The implementation on the other hand says it returns nothing, but that it requires two parameters an integer and an object. // Correct: ... // Prototype for MyFunction void MyFunction( int iNum, object oObject ); ... // In here MyFunction is available for use. // Implementation for MyFunction void MyFunction( int iNum, object oObject ) { ... } Resolved by making the prototype match exactly with the function header. This next sample shows when prototyping a function is a requirement. // Incorrect: // Implementation for MyFunctionA void MyFunctionA( object oPC ) { ... int iB = MyFunctionB( oPC ); // MyFunctionB unknown here. ... } // Implementation for MyFunctionB int MyFunctionB( object oPC ) { ... MyFunctionA( oPC ); ... } The problem is that the function MyFunctionA is trying to call the function MyFunctionB before the implementation for MyFunctionB is known. Switching the functions around so MyFunctionB's implementation appears first will not help in this case because MyFunctionB is also calling MyFunctionA and the same error will show up there instead. // Correct: // Prototype definition for MyFunctionB int MyFunctionB( object oPC ); // Implementation for MyFunctionA void MyFunctionA( object oPC ) { ... int iB = MyFunctionB( oPC ); // this time it's known. ... } // Implementation for MyFunctionB int MyFunctionB( object oPC ) { ... MyFunctionA( oPC ); ... } Resolved by adding a prototype definition for MyFunctionB above the implementation for MyFunctionA so that the compiler will know how to compile the line that calls MyFunctionB before its implementation is known. |
|||
|
// Incorrect: // Some script. void main { ... } The problem is the definition of the script's main function has no parameter list. The main function of a script can never have any parameters, but the empty parameter list enclosed in parenthesis must still appear in order for the compiler to recognize it as a function definition. // Correct: // Some script. void main() { ... } Resolved by adding the empty parameter list to the main function definition. // Incorrect: // Some script. void MyFunction { ... } void main() { ... } The problem is the definition of the custom function called MyFunction has no parameter list. // Correct: // Some script. void MyFunction( int iMyParameter ) { ... } void main() { ... } Resolved by adding an appropriate parameter list to the function header. |
|||
|
|
|||
|
// Incorrect: // Some script. void MyFunction( iValue, strign sName ) { ... } void main() { ... } The problem is the data type specifier for the parameter called iValue in the MyFunction definition is missing. Only the parameter name is present. Also the keyword "string" is misspelled in the declaration of the sName parameter. // Correct: // Some script. void MyFunction( int iValue, string sName ) { ... } void main() { ... } Resolved by ensuring every parameter in the function's parameter list has an appropriate, correctly spelled, data type specified for it. |
|||
|
// Incorrect: // Some script. void main() { int iA = 0; string sB = "1"; if( iA < sB) { ... sB = 7; ... } } The problem is that the variable iA is declared as an integer datatype and the variable iB is declared as a string. The if-statement is attempting to perform a less-than comparison operation between the two variables. Since their datatype does not match, the compiler is unable to translate the boolean expression inside the parenthesis. // Correct: // Some script. void main() { int iA = 22; string sB = "54"; if( iA < StringToInt( sB)) { ... sB = IntToString( 7); ... } } Resolved by ensuring all operations are performed only between operands that have matching datatypes. This is typically facilitated using a function that converts one of the operands to the correct type to match the other. |
|||
|
// Incorrect: // Some script. void main() { switch( d3()) { case 1: ... break; case 3: ... break; case 3: ... break; } } The problem is that the switch statement has two case labels referring to the same value (3). // Correct: // Some script. void main() { switch( d3()) { case 1: ... break; case 2: ... break; case 3: ... break; } } Resolved by making sure all the case labels are unique. // Incorrect: // Some script. const int LOW = 1; const int MEDIUM = 2; const int HIGH = 3; const int AFRAID = 3; const int CAUTIOUS = 5; const int CONFIDENT = 6; void main() { switch( d6()) { case LOW: ... break; case MEDIUM: ... break; case HIGH: ... break; case AFRAID: ... break; case CAUTIOUS: ... break; case CONFIDENT: ... break; } } The problem is that the switch statement has two case labels referring to the same value (3) because the constant names HIGH and AFRAID have both been given the value 3. // Correct: // Some script. const int LOW = 1; const int MEDIUM = 2; const int HIGH = 3; const int AFRAID = 4; // Assign AFRAID a different value. const int CAUTIOUS = 5; const int CONFIDENT = 6; void main() { switch( d6()) { case LOW: ... break; case MEDIUM: ... break; case HIGH: ... break; case AFRAID: ... break; case CAUTIOUS: ... break; case CONFIDENT: ... break; } } - or - // Some script. const int LOW = 1; const int MEDIUM = 2; const int HIGH = 3; const int AFRAID = 3; const int CAUTIOUS = 5; const int CONFIDENT = 6; void main() { switch( d6()) { case LOW: ... break; case MEDIUM: ... break; case HIGH: ... break; // Handles both HIGH and AFRAID. case CAUTIOUS: ... break; case CONFIDENT: ... break; } } Resolved by making sure all constant names used in the case labels of the switch have been given unique values, or by removing all but one of the cases that are being duplicated.. |
|||
|
// Incorrect: // Some script. const int SEVEN = 7; void main() { int iSpell = 0; int iNumber = 0; ... switch( iNumber) { case 1: { ... iSpell = 720; ... } break; case 2 { ... iSpell = 546; ... } break; case SEVEN; { ... iSpell = 22; ... } break; } } The problem is case label 2 has no colon after the 2 and before the {. Also the case label for SEVEN ends with a semicolon instead of a colon. // Correct: // Some script. const int SEVEN = 7; void main() { int iSpell = 0; int iNumber = 0; ... switch( iNumber) { case 1: { ... iSpell = 720; ... } break; case 2: { ... iSpell = 546; ... } break; case SEVEN: { ... iSpell = 22; ... } break; } } Resolved by following the value or constant identifier name of all case labels with a colon. |
|||
|
// Incorrect: // Some TextAppearsWhen script. ... int StartngCondtionale() { ... return TRUE; } The problem is the name of the main function has been misspelled in the function's header line. // Correct: // Some TextAppearsWhen script. ... int StartingConditional() { ... return TRUE; } Resolved by making sure the script has defined one function called StartingConditional that takes no parameters and returns an integer data type. |
|||
|
// Incorrect: // Some script. #include "x0_i0_transport" void main() { object oWP = GetNearestObject( OBJECT_TYPE_WAYPOINT); if( !GetIsObjectValid( oWP)) return; if( GetDistanceToObject( oWP) > 0.25) return; string sTAG = GetTag( oWP); object oDest = OBJECT_INVALID; if( sTAG = "AutoTransport") oDest = GetObjectByTag( GetLocalString( oWP, "Destination"))); else if( sTAG = "HomeTransport") oDest = GetObjectByTag( GetLocalString( OBJECT_SELF, "Home"))); ... if( GetIsObjectValid( oDest)) TransportToWaypoint( OBJECT_SELF, oDest); } The problem is in the if-statements an integer expression is expected in between the parenthesis "(" & ")" where the condition is written. Here the expression has been written as an assignment statement. Since assignment statements evaluate to a value (i.e. the value being assigned), it is legal to use an assignment statement as an expression. However, in this case since both operands to the assignment operator "=" are strings, the datatype of the expression written is a string type...and the compiler is expecting an integer expression there. // Correct: // Some script. #include "x0_i0_transport" void main() { object oWP = GetNearestObject( OBJECT_TYPE_WAYPOINT); if( !GetIsObjectValid( oWP)) return; if( GetDistanceToObject( oWP) > 0.25) return; string sTAG = GetTag( oWP); object oDest = OBJECT_INVALID; if( sTAG == "AutoTransport") oDest = GetObjectByTag( GetLocalString( oWP, "Destination"))); else if( sTAG == "HomeTransport") oDest = GetObjectByTag( GetLocalString( OBJECT_SELF, "Home"))); ... if( GetIsObjectValid( oDest)) TransportToWaypoint( OBJECT_SELF, oDest); } Resolved by changing the "=" operator to a "==" one so the expressions will be computing a boolean (integer) value instead of a string. |
|||
|
// Incorrect: // Some script. void main() { int iA = 3; int iB = Random( iA ) +1; if iA == iB ) // Missing left bracket. { return; } } The problem is the expression used in the if-statement is missing a left bracket. // Correct: // Some script. void main() { int iA = 3; int iB = Random( iA ) +1; if( iA == iB ) // Expression enclosed by a pair of matching brackets. { return; } } Resolved by making sure every one of these ( has a matching one of these ) in the same statement, and every one of these ) has a matching one of these (. Also all the stuff in between them needs to be correct. |
|||
|
// Incorrect: // missing library include here // Some tag-based item script. void main() { if( GetUserDefinedItemEventNumber() != X2_ITEM_EVENT_ACTIVATE) return; ... } The problem is the function GetUserDefinedItemEventNumber is being called but is not defined anywhere. The function definition is in one of the Bioware libraries and the include line for it has been left out. // Correct: // Some tag-based item script. #include "x2_inc_switches" void main() { if( GetUserDefinedItemEventNumber() != X2_ITEM_EVENT_ACTIVATE) return; ... } Resolved by including the library that contains the function definition. |
|||
|
// Incorrect: // Some script. ... void main() { object oNPC = GetObjectByTag( "Some_NPC_Tag"); string sNPCName; sNPCName = GetName( oNPC) // Some comment lines. // Some comment lines. // Some comment lines. // Some comment lines. if( sNPCName == "Paul Speed") // <-- Compiler error points to this line. { PerformIntelligentFeat( oNPC); return; } } The problem is the code statement that assigns the name of the NPC to the variable sNPCName does not end with a semicolon. Note that due to the comment lines which appear between the erroneous statement and the next if-statement, the line number shown in the error message will be several lines past the line that has the missing semicolon. This happens because the compiler doesn't realize the assignment statement should have ended until it encounters the next code statement which is the if-statement (comment lines don't count as code statements). // Correct: // Some script. ... void main() { object oNPC = GetObjectByTag( "Some_NPC_Tag"); string sNPCName; sNPCName = GetName( oNPC); // Some comment lines. // Some comment lines. // Some comment lines. // Some comment lines. if( sNPCName == "Paul Speed") { PerformIntelligentFeat( oNPC); return; } } Resolved by ensuring every code statement ends with a semicolon except those (like the if-statement above) that end with a closing curly brace "}". // Incorrect: // Some script. ... void main() { object oNPC = GetObjectByTag( "Some_NPC_Tag"); string sNPCName; sNPCName = GetName( oNPC)); ... } The problem is that there are too many closing parenthesis at the end of the line that assigns the variable sNPCName a value. The compiler thinks the statement ends after the first closing parenthesis so it expects to see a semicolon or maybe a "+" operator. Instead it encounters another closing parenthesis so it spits out "No semicolon after expression". // Correct: // Some script. ... void main() { object oNPC = GetObjectByTag( "Some_NPC_Tag"); string sNPCName; sNPCName = GetName( oNPC); ... } Resolved by removing the extra parenthesis. |
|||
|
// Incorrect: // Some script. string MyIntToString( int iValue) { if ( iValue == 0) { ... // <-- First Control Path. return "0"; } else { ... // <-- Second Control Path. return IntToString( iValue +1); } ... // <-- Third Control Path. } void main() { ... } The problem is that the MyIntToString function is defined to return a string value. The function has three possible paths of control that can be followed through the code. Since the third path does not end with a return statement that passes out a string value to the function caller, the compiler generates this error. Note that even though it will be impossible to ever reach the third path due to the way the if-statement condition and its then/else blocks are written, the compiler still sees the third path as an alternative. // Correct: // Some script. string MyIntToString( int iValue) { if( iValue == 0) { ... // <-- First Control Path. return "0"; } else { ... // <-- Second Control Path. return IntToString( iValue +1); } return ""; // <-- Third Control Path. } void main() { ... } Resolved by making sure that all control paths through the function bodies of all functions defined in the script which return a non-void type of data end with a return statement used to pass out a value of the correct data type to the function caller. // Incorrect: // Some script. string MyValueToString( int iValue) { switch( iValue) { case 0: return "The value is zero."; case 1: return "The value is one."; default: return "The value is " +IntToString( iValue); } ... } void main() { ... } The problem is that the MyValueToString function is defined to return a string value. The function has four possible paths of control that can be followed through the code. One for each of the cases in the switch statement, and the (unreachable) code that follows the switch statement. Since the final path beyond the switch statement does not end with a return statement that passes out a string value to the function caller, the compiler generates this error. Note that again, even though it will be impossible to ever reach the code past the switch statement due to the use of the default case block and the fact that all the cases return, the compiler still sees that final path as an alternative so it must end with a return. // Correct: // Some script. string MyValueToString( int iValue) { switch( iValue) { case 0: return "The value is zero."; case 1: return "The value is one."; default: return "The value is " +IntToString( iValue); } return ""; } void main() { ... } Resolved by making sure that all control paths through the function bodies of all functions defined in the script which return a non-void type of data end with a return statement used to pass out a value of the correct data type to the function caller. |
|||
|
// Incorrect: // Some script. ... void MyFunction( int iSelector) { if( iSelector == 0) { ... return; } else { ... return 7 } ... } ... The problem is the function MyFunction is defined as void-returning, meaning it does not return a value when called. Yet in the else-part of the if-statement inside the function is a return statement that is attempting to make the function return the integer value 7. In addition, the statement does not have the required terminating semicolon. Making this combination of mistakes will cause ERROR PARSING RETURN STATEMENT to pop up. // Correct: // Some script. ... int MyFunction( int iSelector) { if( iSelector == 0) { ... return 1; } else { ... return 7; } ... return 0; } ... - or - // Some script. ... void MyFunction( int iSelector) { if( iSelector == 0) { ... return; } else { ... return; } ... } ... Resolved by either changing the function definition to make it return a value then editing all return statements in the function to make them return a value, or by removing the value from the offending return statement. And by ensuring there is a semicolon at the end of all statements in the script except those that end with a closing curly brace "}". |
|||
|
// Incorrect: int MyCustomFunctionA() { ... return ""; } string MyCustomFunctionB() { ... float fReturnValue = 0.0; ... return fReturnValue; } The problems are that the function called MyCustomFunctionA is defined to compute an integer value but the return statement in the function is trying to return a string. Also the custom function MyCustomFunctionB is defined to compute a string value but the return statement inside the function is trying to pass out a floating point number. // Correct: int MyCustomFunctionA() { ... return 0; } float MyCustomFunctionB() { ... float fReturnValue = 0.0; ... return fReturnValue; } Resolved by either changing the return statement to return a value of the proper type (as in MyCustomFunctionA above), or by changing the data type the function computes in the function header to match what is being returned (as in MyCustomFunctionB above). // Incorrect: int MyCustomFunction() { ... return; } The problem is that the function called MyCustomFunction is defined to return an integer value but the return statement in the function is not returning any value at all. // Correct: int MyCustomFunction() { ... return 0; } void MyCustomFunction() { ... return; } Resolved by either changing the return statement to pass out a value of the proper type (as in the first fixed version above), or by changing the data type of the function to void (as in the second fixed version above). A void type function returns no value, so any return statements in it must not attempt to return a value either. // Incorrect: void MyCustomFunction() { ... return 0; } The problem is that the function called MyCustomFunction is defined as a void returning function (i.e. it does not compute any value at all), but the return statement in the function is trying to pass out a value (in this case an integer, however a value of any data type appearing in the return statement will cause the error). // Correct: void MyCustomFunction() { ... return; } int MyCustomFunction() { ... return 0; } Resolved by either eliminating the value from the return statement (as in the first fixed version above), or by changing the data type of the function to match the value being returned by the return statement (as in the second fixed version above). |
|||
|
// Incorrect: // Some script. void MyFunction() // Prototype line for the MyFunction function. void myFunction() // Implementation with the name 'misspelled'. { ... } void main() { MyFunction(); // Calling prototyped function with no implementation. } The problem is the prototype line and header line for the function MyFunction don't have the same name. The lower-case 'm' makes them different. When the prototyped name is later used to attempt to call the function, the compiler chokes. Doing this produces the error message with no line number and the <Name> missing. // Correct: // Some script. void MyFunction() void MyFunction() { ... } void main() { MyFunction(); } Resolved by making sure all custom functions called in a script have an implementation defined for them somewhere before they are used. And if the function is prototyped (an optional addition), that the prototype line matches up precisely with the header line of the corresponding function implementation. |
|||
|
// Incorrect: // Some placeable OnUsed script. void main() { object oPC = GetLastUsedBy(); ActivatePortal( oPC, 63.127.247.56:5121 ); } The problem is that the URL entered in the call to the ActivatePortal function is not entered as a string. If you look up the prototype for the ActivatePortal function you will see the second parameter is expected to be a string datatype. Here the quotes around the URL are missing. Since they are not there, the compiler is trying to parse thru the URL to determine what type of data it is, but is unable to identify it as an integer or float or any of the other datatypes it knows about. Therefore, as soon as it hits the second decimal point it realizes the constant is invalid for all datatypes since no datatype exists that allows for more than one decimal point to be used. The second decimal point is an unexpected character so the compiler spits out this message. // Correct: // Some placeable OnUsed script. void main() { object oPC = GetLastUsedBy(); ActivatePortal( oPC, "63.127.247.56:5121" ); } Resolved by passing the URL as a string constant (with quotes around it). It is impossible to show examples for all the various ways this error can be produced, but this is one way it can happen. |
|||
|
// Incorrect: // Some script. void main() { ... switch( iSize) { case SIZE_SMALL: { ... } break; case SIZE_MEDIUM: { ... } break; case SIZE_LARGE: { ... } break; case SIZE_HUGE: { ... } ... } The problem is in the switch statement's SIZE_HUGE case. A scoping block is used to group a bunch of statements there but the closing curly brace that ends the block has been left off. Because the block is not ended, the next curly which is supposed to end the whole switch statement is viewed by the compiler as the end of the case block, and the switch statement (a compound statement) is not complete. // Correct: // Some script. void main() { ... switch( iSize) { case SIZE_SMALL: { ... } break; case SIZE_MEDIUM: { ... } break; case SIZE_LARGE: { ... } break; case SIZE_HUGE: { ... } } ... } Resolved by ensuring your compound statements are correctly structured and that you don't have any unmatched curly braces. |
|||
|
// Incorrect: // Some script. void main() { ... float fBadFloat = .55; string sMessage = "Hello I am " +^ GetName( oNPC); if( (fBadFloat < 1.0) || (sMessage != "") || ) { ... } for( int i = 0; i < 15; i++) { ... } SetLockKeyRequired( object oChest, int nKeyRequired = TRUE); } There are several problems in this script all of which will generate an unknown state in compiler error. The first one is on the fBadFloat line. The value .55 must be written with a 0 in front of the decimal. The second error is on the sMessage line. There are two operators next to each other that don't belong together. The third error is in the condition portion of the if-statement where either one of the three sub-conditions making up the entire compound expression is missing, or there is a superfluous operator added at the end of it. Either way it's not legal to use a binary operator and give it only one operand to operate on. The next error is in the conditional portion of the for-statement. This loop is written using C/C++ syntax where it is legal to define a new variable inside the loop condition. In NWScript, you cannot do this. The variable must be defined independently prior to the for-statement in the code. And the last error is with the call to the function SetLockKeyRequired. Specific datatypes and default values are not entered when you call a function, only when you define it. // Correct: // Some script. void main() { ... float fBadFloat = 0.55; string sMessage = "Hello I am " + GetName( oNPC); if( (fBadFloat < 1.0) || (sMessage != "")) { ... } int i; for( i = 0; i < 15; i++) { ... } object oChest = OBJECT_SELF; int nKeyRequired = TRUE; SetLockKeyRequired( oChest, nKeyRequired); // Use variables. SetLockKeyRequired( OBJECT_SELF, TRUE); // Use values SetLockKeyRequired( oChest, TRUE); // A combination of the two SetLockKeyRequired( oChest); // Rely on default value } The fBadFloat line is resolved by adding a 0 to the front of the number. The sMessage line is resolved by using the + operator correctly by itself to combine the two strings together. The third error is fixed by getting rid of the extra || at the end of the expression. The "for" statement problem is fixed by defining the loop variable separately before the for-statement in the code. And the last line can be resolved in a number of ways. You can define variables, give them values, and pass in the variable name only (no datatype keyword) to the function call. Or you can write the values directly into the function call's parameter list. Or you can do some combination of the two. And in this case, since the function SetLockKeyRequired is defined to utilize a default value of TRUE for the second parameter, you can call the function and leave that parameter out to have the function assume the value TRUE for it. |
|||
|
// Incorrect: // Some script. int y; ... string y; void main() { object y; // This is allowed but it's a different y. All statements in // the main function that use the name "y" will be referring // to this object not the integer defined above. ... int x; if( GetIsPC( y)) // if-statements often introduce nested scoping blocks { float x; // This is allowed but it's a different x in this scope. ... // x in these statements is the float version } // x "the float" goes out of scope here ... // x in these statements is the int variable int x = GetXP( y); ... } // x "the int" goes out of scope here as does the object y The problem is that the definition for the string variable y at the top is invalid because the identifier name "y" is already being used to identify an integer type storage location at the global scope level. Also, in the main function body, a variable by the name of "x" is defined and then later an attempt is being made to redefine it within the same scope as the first definition. // Correct: // Some script. int iY; ... string sY; void main() { object oY; ... int x; if( GetIsPC( oY)) // if-statements often introduce nested scoping blocks { float x; // This is allowed but it's a different x in this scope. ... // x in these statements is the float version } // x "the float" goes out of scope here ... // x in these statements is the int variable x = GetXP( oY); // reuse the first x instead of trying to make a second int exp = GetXP( oY); // or give the new variable a unique name ... } // x "the int" goes out of scope here as does the object oY Resolved by ensuring variable names are all unique within the same scope. |
|||
|
// Incorrect: // Some script. void main() { object oPC = GetFirstPC(); int i; for( i = 0; i < iLoops; i++) { int x = i *2; ... } int y = x; ... } The problem is the variable iLoops is being used in the for-loop but it has never been defined or assigned a value. Also, the variable y is being created and an attempt is being made to assign it an initial value equivalent to the value of the variable x. But the variable x, although previously defined, was defined inside a nested scoping block and no longer exists at the point where y is being defined. Each of these mistakes will get you a VARIABLE DEFINED WITHOUT TYPE error. // Correct: // Some script. void main() { object oPC = GetFirstPC(); int iLoops = (GetHitDice( oPC) /2) +1; int i; for( i = 0; i < iLoops; i++) { int x = i *2; ... } int y = i *2; ... } Resolved by ensuring all variable names being used have been defined prior to their use, and that no variables are being referenced outside of their scope. In this case, that is accomplished by adding a definition for a variable named iLoops, and by not trying to use the variable x when defining the variable y. // Incorrect: // Some script. void main() { object oPC = GetFirstPC(); int iAlignment = GetAlignmentGoodEvil( oPC); int iTeam = 0; if( iAlignment == ALIGNMENT_GOOD) { iTeam = 1; ... } else if( iAlignment == ALIGNMENT_NUTREAL) { iTeam = 2; ... } else if( iAlignment == ALIGNMENT_EVIL) { iTeam = 3; ... } SetLocalInt( oPC, "Team", iTeam); ... } The problem is the Bioware constant for neutral alignment is being used in the second if-statement but has been misspelled. Since no constant has been defined for the incorrectly spelled name, it is an unknown identifier. // Correct: // Some script. void main() { object oPC = GetFirstPC(); int iAlignment = GetAlignmentGoodEvil( oPC); int iTeam = 0; if( iAlignment == ALIGNMENT_GOOD) { iTeam = 1; ... } else if( iAlignment == ALIGNMENT_NEUTRAL) { iTeam = 2; ... } else if( iAlignment == ALIGNMENT_EVIL) { iTeam = 3; ... } SetLocalInt( oPC, "Team", iTeam); ... } Resolved by making sure all referenced variable and constant names are spelled correctly. |