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

Compiler complains about not using module that contains only use its C bindings or global variables #23377

Open
wenxuanjun opened this issue Jan 5, 2025 · 5 comments
Labels
Bug This tag is applied to issues which reports bugs.

Comments

@wenxuanjun
Copy link

wenxuanjun commented Jan 5, 2025

Describe the bug

Compiler complains about not using module that contains only use its C bindings or global variables.

Reproduction Steps

I have a module that use a global variable in another module:

module gop

__global (
	framebuffer &limine.Framebuffer
)
module term

import driver.gop

pub fn init_term() {
	width := framebuffer.width
}

But the compiler warns that module 'gop (driver.gop)' is imported but never used.

The C bindings are in same situation. For example, I have a module that contains C bindings, I can use the C functions defined in it in other modules by importing it:

module log

#include "kprint.c"

fn C.ksuccess(fmt voidptr, ...voidptr)
import log

foo := 123
C.ksuccess(c"Hello, World %d\n", foo)

However, the compiler will warn that module 'log' is imported but never used.

Attempts

For global variables, I can create a wrapper function that returns the global variable:

pub fn get_framebuffer() &limine.Framebuffer {
	return framebuffer
}

And use it in other modules:

// framebuffer := gop.get_framebuffer() // the global variable named `framebuffer` already exists
buffer := gop.get_framebuffer()

For C bindings, perhaps a good practice is to make a V-function wrapper for this c-function:

pub fn success(fmt voidptr, args ...voidptr) {
	C.ksuccess(fmt, ...args)
}

But the variable parameter of the V's function depends on dynamic arrays. Since I'm doing bare-metal development, the generated C code that uses many platform-dependent symbols (e.g. fwrite, stdout) is unusable.

Possible Solution

The compiler should be able to detect the use of global variables or C bindings in a module without warning that the module was imported but never used.

What's more, It would be nice if I could create a V function wrapper and pass variable arguments directly to the C function without create array.

V version

V 0.4.9 3953445

Environment details (OS name and version, etc.)

OS: linux, Linux version 6.12.7-zen1-1-zen (linux-zen@archlinux) (gcc (GCC) 14.2.1 20240910, GNU ld (GNU Binutils) 2.43.0) #1 ZEN SMP PREEMPT_DYNAMIC Fri, 27 Dec 2024 14:24:32 +0000
Processor: 12 cpus, 64bit, little endian, Genuine Intel(R) CPU 0000 @ 2.40GHz

vexe: /usr/lib/vlang/v
vroot: NOT writable, value: /usr/lib/vlang
VMODULES: OK, value: /home/wenxuanjun/.vmodules
VTMP: OK, value: /tmp/v_1000

Git version: git version 2.47.1
CC version: cc (GCC) 14.2.1 20240910

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.

Huly®: V_0.6-21808

@wenxuanjun wenxuanjun added the Bug This tag is applied to issues which reports bugs. label Jan 5, 2025
@wenxuanjun wenxuanjun changed the title Compiler complains about not using module that contains only C bindings Compiler complains about not using module that contains only use its C bindings or global variables Jan 5, 2025
@jorgeluismireles
Copy link

In your second program did you try gop.framebuffer and be shure framebuffer and width are public?:

module term

import driver.gop

pub fn init_term() {
	width := gop.framebuffer.width
}

@wenxuanjun
Copy link
Author

In your second program did you try gop.framebuffer and be shure framebuffer and width are public?:在您的第二个程序中,您是否尝试过 gop.framebuffer 并确保 framebufferwidth 是公开的?:

module term

import driver.gop

pub fn init_term() {
	width := gop.framebuffer.width
}

Hello, thanks for your reply. The second program (module term) is used with the first program (module gop).

For global variables, there is no way to set them to public. We can probably assume it is always public. Because I can use the framebuffer in the term module without importing gop:

module term

pub fn init_term() {
	width := framebuffer.width // ok
}

But I can't access framebuffer via gop.framebuffer:

module term

import driver.gop

pub fn init_term() {
	width := gop.framebuffer.width // error: undefined ident: `driver.gop.framebuffer`
}

So my temporary solution is is the method 1, which is to call width := framebuffer.width directly without importing gop. It works, but it's not intuitive because you don't know which module the framebuffer is coming from.

As for the width, it must be public or there would be no possibility that I would be able to access it.


I also realized that this global variable issue may have something to do with how V manages global variables, i.e. they are available to all modules by default. So this issue may need to be split. Looking forward to your suggestions.

@jorgeluismireles
Copy link

Try structs

module gop

pub struct FrameBuffer {
pub:
	fb limine.Framebuffer
}

and then:

module term

import driver.gop

pub fn init_term() {
    fb := gop.FrameBuffer{}
    println('{fb.fb.width}') // limine.Framebuffer.width should be public, if global make another struct
}

@wenxuanjun
Copy link
Author

Thanks for the reply, but I do need to use global variables because there is the init_gop() function in the gop module, and the term module simply wants to access the initialized framebuffer variable.


I'll briefly describe what happened. For global variables, I was able to use them without importing them, probably because that's the way the V was designed. But for C bindings, if you don't import the module that declares it, you get compiler errors like error: unknown function: C.some_func. If you import it, you get a compiler warning: warning: module 'xxx' is imported but never used. This is definitely not expected to happen.

@jorgeluismireles
Copy link

jorgeluismireles commented Jan 6, 2025

In https://github.com/vlang/v/blob/master/vlib/sokol/f/f.v there are imports of C modules like this:

import sokol.c as _

Seems to me to load the C definitions and to prevent the module marked as not used. Try this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug This tag is applied to issues which reports bugs.
Projects
None yet
Development

No branches or pull requests

2 participants