#Enum Size Issue

10 messages · Page 1 of 1 (latest)

true kelp
#

Hi guys,

Running into an issue with enums and sizes. Might be platform specific (M1 mac), but I don't have access to any other machine right now.

The following fails to compile stating that bar is 8 bytes long, and not 2 as defined (error below):

main :: proc() {
    foo :: enum u16 {
        Smol,
        Enum
    }

    fmt.printfln("foo is %v bytes long",size_of(foo))

    bar :: []u8 { 0, 1 }

    fmt.println("bar is %v", transmute(foo)bar) // fails to compile

}

error:

.scratch/scratch.odin(60:31) Error: Cannot cast 'bar' as 'foo' from '[]u8' 
    fmt.println("bar is %v", foo(bar)) 
                                 ^~^ 
    '[]u8{0, 1}' cannot be represented as the type 'foo' 

relevant version info:

odin version
odin version dev-2024-11

clang -v
Apple clang version 16.0.0 (clang-1600.0.26.4)
Target: arm64-apple-darwin24.1.0
Thread model: posix

The clang version might be wrong, as I might have used homebrew clang to compile and not apple clang.

Am I just abusing transmutation here or is this actually a bug?

royal pelican
#

Error says you are casting while the snippet is doing a transmute, which of the two is mistaken?

#

Could also have to do with bar being a constant

late copper
#

Note that transmute(foo)bar will attempt to transmute the slice itself (a pointer to the data and the number of values), not its contents, which is presumably what you're trying to transmute.

One way around this would be to turn bar into a []foo with slice.reinterpret (from core:slice) and then take the first element. Note that this will be dependent on the endian-ness of the system, since u16 is in native byte order. This approach will give you bounds checking (i.e. that the data was large enough), and also allow you to do multiple at once if you want to

true kelp
#

Yeah, I'm trying to transmute, sorry. And I am trying to transmute the contents. I'll give slice.reinterpret a shot.

#

Might also not have been taking endianness into account. The above example was a boiled down version of what I was running into, which was me translating an array.

The following seems to work:

main :: proc() {
    foo :: enum u16 {
        Smol,
        Enum
    }

    fmt.printfln("foo is %v bytes long",size_of(foo))

    bar :: [2]u8 { 1, 0 }

    fmt.printfln("bar is %v", transmute(foo)bar)

}

Thanks guys!

late copper
#

Endianness should only be a concern if you're trying to exchange info between little-endian systems and big-endian systems, generally

#

And yup, that'll work too. A fixed array is its data, whereas a slice points to its data

true kelp
#

Actual issue I was trying to solve turned out to be completely unrelated. I was getting garbage data when parsing the returned msg_name prop from recvmsg . On linux first struct property is u16, and on mac it is u8. That is why I was getting garbage values when transmuting the array. Had nothing to do with endianness or the compiler not reading the length of the enum when transmuting (which is what I thought was happening)

high olive