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.75k stars 2.16k forks source link

Compile fails if pointer not specified (demonstrated using gg library) #8812

Open Ben-Fields opened 3 years ago

Ben-Fields commented 3 years ago

V version: V 0.2.2 e4a67de OS: Windows 10 64-bit

What did you do? Omitted preceding & to a variable that should be a pointer. Can be demonstrated with the Tetris example (2020-02-17): Change mut game := &Game{ to mut game := Game{ (line 159). Comment out go game.run() (line 175).

What did you expect to see? The program compiles (auto-conversion to pointer as in docs), or the compiler gives the relevant error.

What did you see instead? The program does not compile, and the compiler does not finish executing to give a relevant error. Output: builder error: exec failed (CreateProcess) with code 2: The system cannot find the file specified. cmd: gcc "@C:\Path\To\AppData\Local\Temp\v\tetris.xxxxxx.tmp.c.rsp"

alichraghi commented 3 years ago

Unfortunately, I also faced this problem, but I tried very hard and could not solve it. And finally I had to go back to Linux I think everyone should see this

Ben-Fields commented 3 years ago

Unfortunately, I also faced this problem, but I tried very hard and could not solve it. And finally I had to go back to Linux I think everyone should see this

Whether this is platform-specific or not, the workaround is in the title: be explicit about pointer types. The tetris.v example works just fine without the modifications listed in the report.

spytheman commented 3 years ago

A minimal example for this problem is:

struct Abc { data voidptr }
struct Xyz { x int }
fn main() {
    a := Abc{ data: Xyz{} }
    println(a)
}

which leads to a C compilation error:

/tmp/v/a.12812280819804329601.tmp.c: In function ‘main__main’:
/tmp/v/a.12812280819804329601.tmp.c:8536:36: error: incompatible types when initializing type ‘void *’ using type ‘main__Xyz’ {aka ‘struct main__Xyz’}
 8536 |  main__Abc a = (main__Abc){.data = (main__Xyz){.x = 0,},};
      |                                    ^
scroot commented 3 years ago

Reference document:
https://github.com/vlang/v/blob/master/doc/docs.md#c-types ... To cast a voidptr to a V reference, use user := &User(user_void_ptr). voidptr can also be dereferenced into a V struct through casting: user := User(user_void_ptr).

` struct Abc { data voidptr } struct Xyz { x int y int } fn main() { a := Abc{ data: &Xyz{1,2} } println( &Xyz(a.data)) //ok

b := Xyz(a.data)

} `

./test.v:10:10: error: cannot cast voidptr to struct 8 | println( &Xyz(a.data)) 9 | 10 | b := Xyz(a.data) | ~~~

felipensp commented 3 weeks ago
struct Abc { data voidptr }
struct Xyz { x int }
fn main() {
    a := Abc{ data: Xyz{} }
    println(a)
}

Currently the checker reports:

bug.v:4:15: error: allocate `Xyz` on the heap for use in other functions
    2 | struct Xyz { x int }
    3 | fn main() {
    4 |     a := Abc{ data: Xyz{} }
      |               ~~~~~~~~~~~
    5 |     println(a)
    6 | }
bug.v:4:15: error: cannot assign to field `data`: expected a pointer `voidptr`, but got `Xyz`
    2 | struct Xyz { x int }
    3 | fn main() {
    4 |     a := Abc{ data: Xyz{} }
      |               ~~~~~~~~~~~
    5 |     println(a)
    6 | }