Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Static variables are not maintained correctly #992

Closed
thomasfanell opened this issue Apr 8, 2016 · 4 comments
Closed

Static variables are not maintained correctly #992

thomasfanell opened this issue Apr 8, 2016 · 4 comments

Comments

@thomasfanell
Copy link

Consider this example, where everything works as expected:

Base.ooc

Base: abstract class {
    instanceCount := static 0
    instances ::= static This instanceCount
    init: func {
        This instanceCount += 1
    }
}

Derived1.ooc

import Base
Derived1: class extends Base {
    init: func { super() }
}
//derived1 := Derived1 new()

Derived2.ooc

import Base
Derived2: class extends Base {
    init: func { super() }
 }
 //derived2 := Derived2 new()

main.ooc

import [Base, Derived1, Derived2]

d1 := Derived1 new()
d2 := Derived2 new()

main: func {
    "Instance count: %d" printfln (Base instances) // Instance count: 2
}

Now, if we instead comment out d1 and d2 in main.ooc and uncomment the creation of Derived1 and Derived2 in their respective files, we get Instance count = 1. That is, the static variable is re-initialized for every instance.

@alexnask
Copy link
Collaborator

alexnask commented May 9, 2016

Looking into this now.

@alexnask
Copy link
Collaborator

alexnask commented May 9, 2016

What happens is that the Module load functions call their respective class' load function and both Derived1 and Derived2 (obviously) call their parent's (Base) load function, which resets instanceCount to zero, since multiple executions are allowed.

Basically this means that any side effect on static member initialization will be evaluated multiple times (as many times as you have sublclasses).

Proposed fix is auto generating a static __done__ variable and using it to only evaluate a class' load function once, like we already do with modules.

@alexnask
Copy link
Collaborator

alexnask commented May 9, 2016

On a sidenote, string literals are constructed after class loads which leads to crashes if you try to use one in your static member initialization.

However, I don't think reversing global variable initialization and class load order is wise, since you may initialize a variable that depends on the class' static members.

I will see if there is some way to only reverse the order between (string) literals and class loads.

@alexnask
Copy link
Collaborator

alexnask commented May 9, 2016

@thomasfanell
Will be opening a PR for magic-lang in a bit.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants