Jump to content
zapat

So what makes a variable undefined & how to define it?

Recommended Posts

My question is the title itself.

With this new beta we got this new "feature", but I cannot find any docs on it.

With this new beta I get SOME errors, and I follow the same coding habits in all the 737 282 bytes of my sqf codes. (I should either get no errors, or a lot of them, shouldn't I)

Some variables are flagged undefined, and I cannot make the error go.

Share this post


Link to post
Share on other sites

Post the errors you're getting along with the relevant piece of code - can't really help you otherwise. :)

Share this post


Link to post
Share on other sites

Anytime you use a local variable in a script, you need to define it. Simplest thing to do is in the first line of your script, define every local variable you'll use with the following:

private ["_localVar1","_localVar2","_localVar3"];

Where _localVar1/2/3, etc are the local variables you're using...

Share this post


Link to post
Share on other sites

Fuzzy Bandit: I am wondering about general guidelines. Do we know what makes a variable defined at all?

MeatBall: yes, I thought that private command does the trick. It doesn't. I always use it with local vars, still getting errors. What about Public vars then?

So: Are these defined? (Answer is yes)

MyVar = 12;
MyArray = [];
MyString = "a";

What about: (Answer is yes)

_myList = getPos player nearEntities ["man", 50];

Is this? (Answer is no: for _sameIndex)

//_allActions = [ [1,2,3], [1,2,3] ];
//_index = 0;
_sameIndex = (_allActions select _index);
{
} foreach _sameIndex;

So my question: WHY?

Edited by zapat

Share this post


Link to post
Share on other sites

i think in your case if that is the exact example you have an issue with - _sameIndex is not an array - foreach requires an array - "Executes the given command(s) on every item of an array."

_samIndex is defined but not as an array - Unless _index is an array in itself. Perhaps i have misunderstood your question?

Share this post


Link to post
Share on other sites
Anytime you use a local variable in a script, you need to define it. Simplest thing to do is in the first line of your script, define every local variable you'll use with the following:

private ["_localVar1","_localVar2","_localVar3"];

Where _localVar1/2/3, etc are the local variables you're using...

are you sure it does declare it? So why VAS do a private[] thing and get the errors?

Coding (armaholic) suggested that assigning some value does fix the error for the vas fncCfgDetail thing...

could that be Bis forgot to check the private [] stuff... ?

Share this post


Link to post
Share on other sites

Mikie boy: my question is not about scripting in general, but about declaring variables. My _allactions array is: [ [1,2,3], [1,2,3] ], so a selected element is an array.

It is misunderstandable, true (I corrected my OP), but: anyhow it has nothing to do with declaring a variable IMHO.

This doesn't work: (undefined variable)

_sameIndex = (_allActions select _index);
{
} foreach _sameIndex;  

this does works:

{
} foreach (_allActions select _index);  

So it stinks like a *****.

Share this post


Link to post
Share on other sites
Mikie boy: my question is not about scripting in general, but about declaring variables. My _allactions array is: [ [1,2,3], [1,2,3] ], so a selected element is an array.

It is misunderstandable, true (I corrected my OP), but: anyhow it has nothing to do with declaring a variable IMHO.

This doesn't work: (undefined variable)

_sameIndex = (_allActions select _index);
{
} foreach _sameIndex;  

this does works:

{
} foreach (_allActions select _index);  

So it stinks like a *****.

it must be checked only on assignations, that is what it looks like right now, from the code that works and those that don't.

edit1: BIS why not just putting some effort in an Official IDE, with all the error checking stuff, instead of redoing the wheel again in your arma.exe? Using something like eclipse, or netbean something, that are specialized in code/syntax checking. That would remove the thing out of your main program which is a simulation game. I assume those additions takes some precious Cpu cycles... just a suggestion.

Edited by holo89
suggestion to BIS

Share this post


Link to post
Share on other sites

This works for me without undefined error:

_allActions = [[1,2],3];
_index = 0;

_sameIndex = (_allActions select _index);
{
} forEach _sameIndex;	

Share this post


Link to post
Share on other sites

Kylania: Yes thanks, and I am getting closer. In some cases _allAction is not YET filled, when this code is first called. I am not sure though, as it prints _sameindex = [], when debugging, and not nothing. But the problem must lie there somewhere.

So what BIS is trying to do is to check isNil for variables, before using them? Am I getting this right?

Share this post


Link to post
Share on other sites

Yeah. On my example if all actions wasn't defined you'd get the error on that variable. The odd thing is I swear the first test I did gave an undefined error on same index instead of all actions. So confusing.

I think as long as we just declare the data types of all variables we'll be good.

Share this post


Link to post
Share on other sites

An undefined variable is just that, a variable that has not been defined with any kind of supported data types.

//Undefined variable
5 + _five;

//Defined variable
_five = 5;

5 + _five;

Share this post


Link to post
Share on other sites
An undefined variable is just that, a variable that has not been defined with any kind of supported data types.

//Undefined variable
5 + _five;

//Defined variable
_five = 5;

5 + _five;

so if you have a variable like:

somethingdone = true

how do you define that? Or is that already defined?

Share this post


Link to post
Share on other sites

Is this? (Answer is no: for _sameIndex)

//_allActions = [ [1,2,3], [1,2,3] ];
//_index = 0;
_sameIndex = (_allActions select _index);
{
} foreach _sameIndex;

So my question: WHY?

_sameIndex is undefined because there are used undefined (=nonexisting) variables to define it. There is no value for _allActions and there is no value for _index. This code isn't able to create anything (except error message) when you give that script command select two nonexisting (=undefined) variables.

Share this post


Link to post
Share on other sites

An undefined variable means that the variable you are trying to access has not been assigned to anything.

As neokika says, if at any point in your code you're doing:

_a = 1;

then "_a" is defined, as "single equals" character is the assignment operator.

Some examples:

// a.sqf
// This is ok, a has been defined and we're trying to access it
_a = "hi";
hint _a;

// b.sqf
// This is bad, we're trying to access b before it has been defined, we'll get an error because engine doesn't know what "_b" stands for, meaning that variable "_b" is undefined

hint _b;
_b = "bye";

// c.sqf
// We have a unit named joe in the mission, and a trigger that we can call to exectute c.sqf

if(alive joe) then {
   _c = "Joe is alive!";
};

// If joe is alive when we execute c.sqf, "_c" will be defined and everything is ok, 
// but if joe is dead when we execute c.sqf, "_c" will not be defined (because the if condition failed and the code inside it never executed) and you'll get an error
hint _c;

// d.sqf
// We have a unit named jack in the mission, and a trigger that we can call to exectute d.sqf

if(alive jack) then {
   _d = "Jack is alive!";
} else {
   _d = "Jack is dead!";
};

// This is ok again, because even if Jack is dead when we execute d.sqf, we're defining "_d" to some value
hint _d;

Edited by Sniperwolf572

Share this post


Link to post
Share on other sites

Hmmmm how would I declare

 _x

then

error:

Error Undefined variable in expression: _x

if (!isnull _x && alive _x && !captive _x ) then {	
>
 Error position: <_x && alive _x && !captive _x ) then {	
>

Share this post


Link to post
Share on other sites
_sameIndex is undefined because there are used undefined (=nonexisting) variables to define it. There is no value for _allActions and there is no value for _index. This code isn't able to create anything (except error message) when you give that script command select two nonexisting (=undefined) variables.

since it was probably working before the patch, and not after, I assume it is define in another script (scope)? and if so, will arma give an error anyway since it is not in the script? or is it evaluated at run time?

Share this post


Link to post
Share on other sites

You wouldn't declare _x as it's a special variable for "current value of" within a forEach.

This code works for your example without declaring _x:

_npcs = [c1, c2];

{
if (!isnull _x && alive _x && !captive _x) then {
	player sideChat format["%1 is ok", name _x];
};

} forEach _npcs;

Just make sure _npcs is properly declared.

Share this post


Link to post
Share on other sites
Hmmmm how would I declare
 _x

then

error:

Error Undefined variable in expression: _x

if (!isnull _x && alive _x && !captive _x ) then {	
>
 Error position: <_x && alive _x && !captive _x ) then {	
>

_x is a magic variable in the engine for iterator loops, otherwise it holds no meaning until defined, since you're not giving me the full code, I'll mash something up around the error you provided:

// _x is not defined here
{
   // Inside these brackets _x is a magic variable pointing to a member of the players group
   // outside the brackets _x is undefined
   if (alive _x && !captive _x) then {
       sideRadio "woot"; // If the unit is alive and not captive, this will execute
   };
} foreach units group player;

// _x is not defined here again

// The result will be a "woot" radio message the same amount of times as the number of alive and non captive members of players group

// This will produce errors as _x is not defined anywhere
if (alive _x && !captive _x ) then {
   sideRadio "Yep";
}

// This will not produce errors as _x is a reference to the player, but _x shouldn't be used in such manner so it doesn't conflict with it's magic _x inside the iterator loops

_x = player;
if (alive _x && !captive _x ) then {
   sideRadio "Yep";
}

// Now this is a bit more advanced
// This will not produce errors as we're doing lazy evaluation
// Lazy evaluation means that if in a chain of conditions, if at any point there is something that would fail the entire condition, subsequent conditions are not checked

// In the case below, with lazy evaluation isnil checks if "_x" is defined, if it's not, then it will not try to do "alive _x" and "!captive _x"
if (!isnil('_x') && {alive _x} && {!captive _x} ) then {
   sideRadio "Yep";
}

// But this here would produce an error because even if "_x" ends up being undefined for the "!isnil('_x')" check, the engine will eagerly check the subsequent "alive _x" and "!captive _x" conditions instead of failing of the first one and saving the resources and execution time
if (!isnil('_x') && alive _x && !captive _x ) then {
   sideRadio "Yep";
}

Edited by Sniperwolf572
  • Like 1

Share this post


Link to post
Share on other sites

Thanks for all the answers, and the developers' time as well!

You need to take a lot more care now! It is easy to get something that became nil while the code ran to be assigned to _x!

I have just realized. :) (eg. deleting a unit)

The problem is that we have had a system, that didn't give us errors, but nothing happened instead, when such happened. And me for exapmle, I didn't bothered with these, although I knew that in some rare cases _x may become nil, but I said: "and then what: condition won't return true". It is now an error.

Share this post


Link to post
Share on other sites

so if I understand well,

in:

_a = _b;

we can no more assign a variable _b to _a if _b is not define. so undefined variable evaluate no more to 'nil' or something like that. (or will not, since scripts seems to work anyway as they still check for nil)

and it is true only for assignment.

for evaluation like:

if (isNil (_b select 0)) then...

will this throw an error if _b is undefined at run time? that is something that is used a lot ....

Share this post


Link to post
Share on other sites

You can do everything you could do yesterday, only today you're getting a warning if it's undefined. Basically you can keep doing things the lazy incorrect way but now you're gonna get called on it. Everything still works the same though.

Get in the habit of defining variables and you'll have a good time.

Share this post


Link to post
Share on other sites

Basically, those are mistakes in code, or well, bugs. If you're trying to do something with something that does not exist, then the engine will give you an error and carry on just like before, the only thing is, now you'll be told that there is something wrong with your script and it might not behave as you expected. If something has a potential to be undefined in your code, then you have to account for that with "isnil" checks before you preform operations on the potentially undefined variables.

Think of it like this, you and me walk into an empty room that only has a table in it.

You: "Hey, Sniperwolf572, sit on the chair"

Me: "What? Please tell me what do you mean by chair, because I see no chair in this room. What do you expect me to do?"

Then we walk back out again, but this time you fixed your script for telling me to sit and we walk back in

You: "Hey, Sniperwolf572, when I say chair, I mean table."

Me: "Ok!"

You: "Sit on the chair."

Me: "Ok!"

And then I proceed to sit on the table.

Edited by Sniperwolf572

Share this post


Link to post
Share on other sites

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now

×