It is the effect of the different compiler. You can not declare variables in the case statement with the standard compiler.
I am a little surprised the skywings compiler allows it. But I guess is a glass half full/ half empty type of thing if you are counting the number of instructions executed to avoid TMI errors.
The only way I can see skywings compiler allowing it, is if all the variables you are declaring in the script ( or at least the ones you are declaring in the switch ) are having stack space reserved for them regardless of program flow. .
The reason the declaration does not work, is the same reason this
if (a) int b;
does not work.
but this
if (a) {int b;}
does.
Detailed Answer.
In the standard nwn compiler space is reserved for the variable when the declaration is executed in the code. The memory/ stack is freed/cleaned at the end of the name space or when the variable no longer has scope.
When the variable is accessed in the code the memory location that it represents is found via an offset from either the Top Of the Stack or a base pointer that points to a know point in the stack. The Top Of Stack pointer (TOS) points at the top of the stack so that everything above it currently unused and everything below where it is pointing is being used.
For simplicity lets just consider the stack as an array of dwords that already had enough memory allocated to it to hold what every we want. And the TOS pointer having the index of the first unused dword.
So given the following code fragment.
int a;
int b = 5;
a= GetSwitchvalue();
switch(a)
case 1:
int c;
case 2:
{ // something or other.}
default:
{// some randon code}
b=1;
line 1: : int a;
when the 'int a;' is executed the only thing that happens is the TOS pointer is increased by 1. So if it was currently 54 it is now 55 but we really have no Idea where it's starting point is. So the variable 'a' at this point in the code would be in the index of TOS -1 concidering our stack as an array we would have STACK[TOS -1] but this will change with every thin that happens with the stack.
line 2: int b =5;
The TOS is increased by one again to reserve space for the b variable. Then it is increased again to push the constant 5 onto the top of the stack. So at this mid stage we have:
reserved space for (var a) at TOS -3
reserved space for (var at TOS -2 and
the constant 5 stored at TOS -1
the assignment operator moves whatever is on the top of the stack (TOS-1) to an offset from the TOS and decreases the TOS by one. In this case the offset to move the top of the stack to would be -2 because that is where we know the reserved space for var b is at.
So at the point line 2 is finished var b is at TOS-1 and var a is at TOS-2. even though they where not constantly in the same offsets during even the execution of the line.
line 3: a = GetSwitchvalue();
The execution of this statement is going to start with the execution of the function. assuming that it compiled we can tell that the function is an int returning function. code from somewhere else is going to execute and the stack pointer is going to go up and down and who know what. but this is know. once the code for the function is finished the stack pointer is going to be increased by one with a new integer on the top of the stack that was returned by the function. ( This by the way is why the function header is needed before the function can be used in the code but not necessarily the entire function body. at this point in the compiling process only the net result to the stack needs to be known, to keep track of the vars, and not where or what the function is. that will be filled in with another pass of the compiler.)
Stack after the function looks like.
TOS-1 returned integer from the GetSwitchvalue() function.
TOS-2 storage for var b
TOS-3 Storage for var a
to finish off the statement only the assignment need to take place.
TOS-1 is moved to TOS-3 and the Stack is reduced by 1 to trim the return value from the stack.
So the stack is once again at
TOS-1 storage for b with 5 stored in it from the line 2.
TOS-2 Storage for a with the new return value now stored in it.
Line 4: switch(a)
with the execution of this control structure, the value Var-a at known offset of TOS-2 is going to be pushed to the top of the stack some comparisons are going to be made to decide where execution continues at. the top of the stack will be popped off and a jump in execution will will be made to either line 6,8 or 10. .
Line 5,7 and 9: case 1; case 2: and default:
No code is injected for any of these lines they simply reference points to the compiler for a future pass when it fills in the jump offsets for the switch statement.
Line 6: int c;
The TOS is increased by one with storage reserved for Var-c
Skipping down to line 11.
Line 11: b=1;
ok we move the constant 1 to the top of the stack.
and move that value to the offset where b is at.... Hmmm.
did line 6 execute?
Is the stack currently.
TOS -1 The constant one just pushed here.
TOS-2 c from line 6 ?? or is it var b ??....
So at this point the compiler need to move the top of the stack to either TOS -2 if line 6 did not execute or TOS-3 if it did execute. since the offset need to be known at the time of compiling and can not change this thrown a major fly into the ointment.
So you may ask why would {int c;} work where int c; does not. The answer is rather simple. The } declares the end of the name space. c simply has no scope outside of the {} once the closing } all vars that where created within that block of code are removed from the stack, leaving the stack in the same state it was in before the opening {
Hope no one minds how long winded I got.
L8