vlang / v

Simple, fast, safe, compiled language for developing maintainable software. Compiles itself in <1s with zero library dependencies. Supports automatic C => V translation. https://vlang.io
MIT License
35.79k stars 2.16k forks source link

RUNTIME ERROR: invalid memory access #22445

Open ufm opened 3 weeks ago

ufm commented 3 weeks ago

Describe the bug

RUNTIME ERROR: invalid memory access

Reproduction Steps

fn main() {
    m := { "1":"1", "2":"2" }
    if b := m["1"] {
        defer { println(b)}
        println("ok")
    }
}

Result:

ufm@ufmpc:~/src/vtest$ ./vt
ok

ufm@ufmpc:~/src/vtest$ ./vt
ok

ufm@ufmpc:~/src/vtest$ ./vt
ok

ufm@ufmpc:~/src/vtest$ ./vt
ok

ufm@ufmpc:~/src/vtest$ ./vt
ok
0x774c4afa07cd: at ???: RUNTIME ERROR: invalid memory access
0x01f69500: by ???
Segmentation fault (core dumped)

Expected Behavior

Get the value of "b" or get a compiler error saying that this is not allowed.

Current Behavior

0x7178a25a07cd: at ???: RUNTIME ERROR: invalid memory access 0x02892500: by ??? Segmentation fault (core dumped)

Possible Solution

No response

Additional Information/Context

No response

V version

0.4.8 e1b842a

Environment details (OS name and version, etc.)

Linux

[!NOTE] You can use the πŸ‘ reaction to increase the issue's priority for developers.

Please note that only the πŸ‘ reaction to the issue itself counts as a vote. Other reactions and those to comments will not be taken into account.

esquerbatua commented 2 weeks ago

Removed the typo of dot in the example: if b := m["1"] {. -> if b := m["1"] {

spytheman commented 2 weeks ago

It is a problem, that will get solved when defer becomes scoped.

Currently defer will defer the execution till the function end, at which point b is no longer well defined.

ufm commented 2 weeks ago

I believe the language authors know best how to address this issue, but there are essentially three options:

  1. Track variable escapes and disallow such behavior at the compilation stage.
  2. Treat it as a regular closure.
  3. Call defer not when exiting the function, but when exiting the block.

I like the third option the most. But it's up to the authors to decide.

spytheman commented 2 weeks ago

Yes, option 3 is the one that will be implemented. We already have a plan for our defer construct to be scoped by default, instead of the current behavior.