#Inconsistent behavior with static variables in functions/methods

41 messages · Page 1 of 1 (latest)

median meadow
#

I've been experimenting with using static variables within functions and referencing them outside of the function, and am running into some issues.

I'm using a completely blank project with just one object in the room. In the object's Create event I define a function with a static variable in it

function test() { static num = 1; }

We also want to execute the function at least once so that the static variable gets initialized, so we write test(); in the create event as well

Then, in the objects Key Press - Space event I show a message that prints that static variable

show_message($"test: {test.num}");

Now, we'd expect that pressing the space bar would now show a message containing the static variable as a string like so:

test: 1

But instead, we get this error message

Variable <unknown_object>.num(100003, -2147483648) not set before reading it.
at gml_Object_oGame_KeyPress_32 (line 1) - show_message(test.num);

This seems incorrect, and goes against what the manual says about static variables.

But, if I move the function declaration and the initial execution of said function into the space pressed event, then it fixes the issue, and prints the static variable.

And there is a way to break it again. By changing the function declaration from

function test()

to

test = function()

The error comes back.

Finally, if I move the function declaration to a script asset, then it will print the static variable, but only if I use the function test() syntax

I don't have the time to revert my gamemaker version back to see if that fixes the issue, but I don't see how this isn't a bug with gamemaker.
Is there something obvious I'm missing here?

tired hazel
#

Even if you do

function test() {
    static num = 1;
}
#

It’ll look global in the IDE

#

But not on the compiler end

#

(Code editor 2 would resolve these kinds of issues, but that’s in beta)

#

And therefore, wherever an object could access “test”, would only work if you can access that specific object instance + name of method

#

As for methods in general

#

There is a bug report on this already, for 2024.4

#

But the problem is that because it’s a method and not a function, you can’t just access static variables that way

#

Instead you need to do

#

method_get_index(test).num

quartz loomBOT
#

This function gives you the Script Function reference for the given method. This can be used to retrieve the original function behind a method bound to an instance or a struct.

Arguments
method: The method variable to check

tired hazel
#

You might also have to throw in static_get too

quartz loomBOT
#

This function returns the static struct for the given function or struct.

Arguments
struct_or_func_name: The struct or function for which to get the static struct

tired hazel
#

static_get(method_get_index(test)).num

median meadow
#

trying it out rn

#

yep that works

#

they really should add that to the manual

#

unless they did and i missed it

tired hazel
#

They did, on this page

#

At least on how methods/functions are handled

#

They haven't covered static_get as it wasn't really reported until recently

#

So a bug

median meadow
#

thank you for the help!

#

so is there any real distinction between defining a function like
function test() {}
or
test = function() {}

tired hazel
#

Well there's a couple of differences

#

But it depends

median meadow
#

i always interepreted it as the latter being a method and the former being a normal function

tired hazel
#

If you define this in a script, the former is a global function

#

The latter is also global, but requires to be accessed with global.

#

If it's in an object

#

It's always a method

#

Which helps differ even moreso, and covers a couple cases

#

Basically, if you're defining a function that is to be used anywhere, then you should always be using the former in a script

#

Otherwise, use the latter in objects/constructors/structs

median meadow
#

got it, thanks again!