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

v_sprintf bug? #23767

Open
mecolosimo opened this issue Feb 19, 2025 · 9 comments
Open

v_sprintf bug? #23767

mecolosimo opened this issue Feb 19, 2025 · 9 comments

Comments

@mecolosimo
Copy link

mecolosimo commented Feb 19, 2025

V version: V 0.4.9 af3f6c1, press to see full `v doctor` output
V full version V 0.4.9 2684ef9.af3f6c1
OS linux, Linux Mint 22
Processor 8 cpus, 64bit, little endian, AMD Ryzen 5 7520U with Radeon Graphics
Memory 0.94GB/14.86GB
V executable /home/mcolosimo/github/v/v
V last modified time 2025-02-19 19:58:06
V home dir OK, value: /home/mcolosimo/github/v
VMODULES OK, value: /home/mcolosimo/.vmodules
VTMP OK, value: /tmp/v_1000
Current working dir OK, value: /home/mcolosimo/SyncProjects/mecolosimo/unsafe
Git version git version 2.43.0
V git status weekly.2025.08-10-gaf3f6c18
.git/config present true
cc version cc (Ubuntu 13.3.0-6ubuntu2~24.04) 13.3.0
gcc version gcc (Ubuntu 13.3.0-6ubuntu2~24.04) 13.3.0
clang version N/A
tcc version tcc version 0.9.28rc 2024-07-31 HEAD@1cee0908 (x86_64 Linux)
tcc git status thirdparty-linux-amd64 0134e9b9
emcc version N/A
glibc version ldd (Ubuntu GLIBC 2.39-0ubuntu8.4) 2.39

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

import strconv

struct Foo {
mut:
    x u8
}

fn main() {
	mut fc := Foo{u8(1)}
	println(fc.x)
	// x := int(fc.x)
	s := unsafe { strconv.v_sprintf("x=%02d", fc.x) }  
      // unsafe { strconv.v_sprintf("x=%02d", x) } works
      // unsafe { strconv.v_sprintf("x=%02d", int(fc.x)) } doesn't build
	print(s)
}

What did you see?

1
x=-1269080063

What did you expect to see?

1
x=01

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.

Copy link

Connected to Huly®: V_0.6-22181

@mecolosimo
Copy link
Author

src/main.v:12:44: error: expression cannot be passed as `voidptr`
   10 |     println(fc.x)
   11 |     s := unsafe { strconv.v_sprintf("x=%02d", int(fc.x) )} 
      |                                               ~~~~~~~~~
   12 | }

but this works correctly

fn main() {
	mut fc := Foo{u8(1)}
	println(fc.x)
	x := int(fc.x)
	s := unsafe { strconv.v_sprintf("x=%02d", x )} 
	println(s)
}

Shouldn't these be the same, unless it processes them differently?

@mecolosimo
Copy link
Author

pub fn v_sprintf(str string, pt ...voidptr) string 

So int(fc.x) can't be converted to voidptr but fc.x which is u8 can?

@jorgeluismireles
Copy link

This worked for me:

import strconv

struct Foo {
mut:
    x u8
}

fn main() {
	mut fc := Foo{u8(1)}
	println(fc.x) // 1
	x := int(fc.x) 
	s := unsafe { strconv.v_sprintf("x=%02d\n", voidptr(&x)) }  
	print(s) // x=01
}

@mecolosimo
Copy link
Author

this doesn't which should be the same thing.

import strconv

struct Foo {
mut:
    x u8
}

mut fc := Foo{u8(1)}
println(fc.x)
x := voidptr(&(int(fc.x)))
s := unsafe { strconv.v_sprintf("x=%02d", x) }
Can't run code. The server returned an error:
/tmp/v_60000/../../../../../../box/code.v:10: error: lvalue expected

I should point out that spintf is doing the "correct" thing. I told it to except and int, it just happens it was expecting 32 bits (this is why c sucks, I remember when ints where 8 bits and we had to check if they were 16 , since most computers where still 8 bit).

@jorgeluismireles
Copy link

I think the problem are u8 and u16 that should be promoted to u32 at least (which is int) and copied to a real memory space where V compiler could apply voidptr for us, since this works without using unsafe:

import strconv

struct Foo {
mut:
    x u8
}

fn main() {
	mut fc := Foo{u8(1)}
	x := u32(fc.x) // new space big enough here
	s := strconv.v_sprintf("x=%02d", x)
	println(s)
}

variables like u32, u64, f32, f64 can be sprinted directly without unsafe

@JalonSolov
Copy link
Contributor

int is i32, not u32, and only until the change, but for now, at least both i32 and u32 take the same amount of space.

@mecolosimo
Copy link
Author

What i32 and u32 at some point will not use the same space! Also more of v_sprintf:

@[direct_array_access; manualfree; unsafe]
pub fn v_sprintf(str string, pt ...voidptr) string {

it says its unsafe. So I assumed to use it in an unsafe block!

@JalonSolov
Copy link
Contributor

i32 and u32 will. int and i32 won't. The plan is to change int so that it acts like int in Go - it will be i32 on 32-bit systems, i64 on 64-bit systems.

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

No branches or pull requests

3 participants