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.67k stars 2.15k forks source link

builder: Putting a function reference inside a voidptr in a struct generate bad C code #12347

Open SheatNoisette opened 2 years ago

SheatNoisette commented 2 years ago

V doctor:

OS: linux, Linux version 5.14.13-200.fc34.x86_64 (mockbuild@bkernel02.iad2.fedoraproject.org) (gcc (GCC) 11.2.1 20210728 (Red Hat 11.2.1-1), GNU ld version 2.35.2-6.fc34) #1 SMP Mon Oct 18 12:39:31 UTC 2021
Processor: 16 cpus, 64bit, little endian, AMD Ryzen 7 5800X 8-Core Processor
CC version: cc (GCC) 11.2.1 20210728 (Red Hat 11.2.1-1)

getwd: /home/sheat/Documents/Projects/v/experiments
vmodules: /home/sheat/.vmodules
vroot: /home/sheat/Documents/Tools/v
vexe: /home/sheat/Documents/Tools/v/v
vexe mtime: 2021-10-31 15:11:07
is vroot writable: true
is vmodules writable: true
V full version: V 0.2.4 6937074.28cada3

Git version: git version 2.31.1
Git vroot status: weekly.2021.43-57-g28cada3f
.git/config present: true
thirdparty/tcc status: thirdparty-linux-amd64 333c14de

What did you do? v -g -o vdbg cmd/v && vdbg bug.v

module main

struct Struct_voidptr
{
    func voidptr
}

fn function() {
    println("Function!")
}

fn main() {
    fun := function

    sct := &Struct_voidptr{
        func: &fun
    }

    fun()
    sct.func
}

What did you expect to see?

A generated executable.

What did you see instead? V generated invalid C code, no warning(s) or error(s) from V compiler.

==================
/tmp/v/bug.8683824993859103714.tmp.c:10662: error: identifier expected
...
==================
(Use `v -cg` to print the entire error message)

builder error: 
==================
C error. This should never happen.

This is a compiler bug, please report it using `v bug file.v`.

https://github.com/vlang/v/issues/new/choose

You can also use #help on Discord: https://discord.gg/vlang
DevrosTheOne commented 2 years ago

Hmm. The voidptr is just a pointer type in V. Not sure you can/should cast a void pointer to a function in V?
It has no information about parameters or return requirements for a function. Define the variable specifying the type of function to accept.

    func fn ()

Is something like this you are after?

module main

struct Struct_voidptr{
    func fn ()  // func is a function with no parameters and no return
}

fn function() {
    println("Function!")
}

fn main() {
    fun := &function

    sct := &Struct_voidptr{
        func: fun  // same as *fun
    }

    fun()
    sct.func()  // call the stored function from structure on heap
}

output

Function!
Function!

You don't actually need the address operator and can use the address to the function or access the address directly from the copy in the variable.

    fun := function  // fn ()

    sct := &Struct_voidptr{
        func: fun  // or use 'function' directly
    }

Sorry for being verbose. Old habits die hard.

Compilation should have thrown a compiler error and not the C error. This should never happen.

SheatNoisette commented 2 years ago

I was just messing around with the compiler and found this. I was hoping for a V error and instead it generated C code where it shouldn't.

DevrosTheOne commented 2 years ago

I was just messing around with the compiler and found this. I was hoping for a V error and instead it generated C code where it shouldn't.

Thought that might have been the case. Happy to delete the post if needed.

SheatNoisette commented 2 years ago

No need to delete the post. It's a good example of a function pointer. Btw, I may be wrong but I don't think the doc explain this concept ?

Anyway, I think this is a bug.