Skip to content

transmute slice from #load adjusts slice size #2221

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

Open
ryhor-spivak opened this issue Nov 29, 2022 · 2 comments
Open

transmute slice from #load adjusts slice size #2221

ryhor-spivak opened this issue Nov 29, 2022 · 2 comments
Labels

Comments

@ryhor-spivak
Copy link
Contributor

package main
import "core:fmt"
main :: proc()
{
	embed_u32 := transmute([]u32) #load("embed") // 8 bytes file just like literal below
	src_u32 := transmute([]u32) []u8{31,32,33,34,35,36,37,38}
	fmt.printf( "embed_u32 len %d\nsrc_u32 len %d\n", len(embed_u32) , len(src_u32) )
}

This prints:
embed_u32 len 2
src_u32 len 8

Somehow transmuting []u8 slice returned by #load() readjusts slice length from 8 to 2. But with slice literal this doesn't work. As I understand mem.slice_data_cast should be used here. But it is very confusing why transmute([]u32) works differently on slices returned by #load()

    Odin: dev-2022-11-nightly:382bd876
    OS:   Windows 10 Unknown Edition (00000064) (version: 21H2), build 19044.2251
    CPU:  AMD Ryzen 7 5800HS with Radeon Graphics
    RAM:  15775 MiB
@gingerBill
Copy link
Member

You are incorrectly using both #load and transmute.

transmute just reinterprets the bits to whatever type you specified.

What I am guessing you want wanting to use it the following:

#load("embed", []u32)

This will interpret the file as if it is an array of u32.

@Kelimion Kelimion reopened this Nov 29, 2022
@Kelimion
Copy link
Member

It is a bug, though. Make a file called eight.txt with contents 12345678, run this:

main :: proc() {
	DATA  :: #load("eight.txt")
	D32   :: transmute([]u32)#load("eight.txt")
	fmt.println(len(DATA), len(D32))
}

Prints: 8 2

This means that D32 :: transmute([]u32)#load("eight.txt") is treated as #load("eight.txt", []u32), even though if it had really been a transmute bit cast, the length would've remained 8.

Also interesting is that _D32 :: transmute([]u32)DATA gives you the expected error that you can't transmute a constant, but when used directly on #load as above it is allowed (and does the wrong thing).

Here you have the expected behavior that _D32 contains 8 elements despite having a backing for only 2, i.e. a user error. So the bug is either that transmute([]u32)#load is allowed, or that it doesn't evince the same user error.

main :: proc() {
	DATA  :: #load("eight.txt")
	D32   :: transmute([]u32)#load("eight.txt")
	fmt.println(len(DATA), len(D32))

	data  := DATA
	_D32  := transmute([]u32)data
	fmt.println(D32)
	fmt.println(_D32)
}

@github-actions github-actions bot added the stale label Mar 29, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants