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

&string interpolation with += string #23460

Closed
Eliyaan opened this issue Jan 13, 2025 · 8 comments
Closed

&string interpolation with += string #23460

Eliyaan opened this issue Jan 13, 2025 · 8 comments

Comments

@Eliyaan
Copy link
Contributor

Eliyaan commented Jan 13, 2025

V version: V 0.4.9 a20fff9, press to see full `v doctor` output
V full version V 0.4.9 6ac1d08.a20fff9
OS linux, "Void Linux"
Processor 4 cpus, 64bit, little endian, Intel(R) Pentium(R) Gold 7505 @ 2.00GHz
Memory 16.67GB/23.16GB
V executable /home/nopana/v/v
V last modified time 2025-01-13 21:21:06
V home dir OK, value: /home/nopana/v
VMODULES OK, value: /home/nopana/.vmodules
VTMP OK, value: /tmp/v_1000
Current working dir OK, value: /home/nopana/projects/tests
Git version git version 2.47.1
V git status weekly.2025.1-44-ga20fff99
.git/config present true
cc version cc (GCC) 13.2.0
gcc version gcc (GCC) 13.2.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 (GNU libc) 2.39

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

mut s := "Hello"
mut p := &s
p += s

What did you see?

bug.v:3:3: warning: pointer arithmetic is only allowed in `unsafe` blocks
    1 | mut s := "Hello"
    2 | mut p := &s
    3 | p += s
      |   ~~
bug.v:2:5: warning: unused variable: `p`
    1 | mut s := "Hello"
    2 | mut p := &s
      |     ^
    3 | p += s
bug.v:3:3: error: mismatched types `&string` and `string`
    1 | mut s := "Hello"
    2 | mut p := &s
    3 | p += s
      |   ~~
bug.v:3:1: error: operator `+=` not defined on left operand type `string`
    1 | mut s := "Hello"
    2 | mut p := &s
    3 | p += s
      | ^

What did you expect to see?

To say it is not defined on &string (because it is defined for string). But I dont know if it should allow for &string += string .

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-21890

@JalonSolov
Copy link
Contributor

What did you expect to happen with your example? Looks you're trying to add a string to a string pointer, which is exactly what V said.

@jorgeluismireles
Copy link

This works even without mut in the playground:

fn main() {
	s := "Hello"
	p := &s
	unsafe { *p += s }
	println('${*p}') // prints HelloHello
}

@jorgeluismireles
Copy link

Exponential grow without mut:

fn main() {
	s := "Hello"
	p := &s
	for i := 0; i < 4; i++ {
		unsafe { *p += *p }
	}
	println('${s}') // Hello 2^4 = 16 times
}

@Eliyaan
Copy link
Contributor Author

Eliyaan commented Jan 13, 2025

I guess I did not understand properly what V meant by "pointer arithmetic".
I wanted to concatenate a string to the string stored in the reference

Also it says that += is not defined on type string, instead of &string

@JalonSolov
Copy link
Contributor

No, += is not defined for adding a string to a pointer.

And adding a string to the string pointed to by a pointer will just overwrite unallocated memory (or worse, allocated for something else). Both of @jorgeluismireles options may "work", but they have corrupted memory beyond what was correctly allocated for s.

The string struct also has not been properly updated, so s.len will be incorrect, and when it is free'd, it will only free what was originally allocated for s, not the extra that was crammed onto the end through pointers. Valgrind will certainly complain about the leaked memory, supposing your code doesn't crash the machine (depending on what gets overwritten).

So, although it is certainly possible to make this kind of thing work, it is definitely unsafe, and should never be used... at least without a lot more code added to make sure memory is properly allocated, and the struct for s properly updated.

@jorgeluismireles
Copy link

V pointer arithmetic message seems to be like the C pointer arithmetic, but seems is not. In C, with pointer arithmetic you can read and write each byte of an integer, struct, string, array... having the start of the object. But you are in your own because you can modify parts of other objects adjacent set by the compiler and create unexpected bugs or create viruses or security threats. In V seems to be just the possibility of use the += operator, but as is marked you are not safe.

@Eliyaan
Copy link
Contributor Author

Eliyaan commented Jan 14, 2025

Okay thank you!

@Eliyaan Eliyaan closed this as completed Jan 14, 2025
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