v icon indicating copy to clipboard operation
v copied to clipboard

error: cannot convert 'struct array' to 'short'

Open refaqtor opened this issue 4 years ago • 7 comments

V doctor:

OS: linux, Pop!_OS 20.04 LTS
Processor: 24 cpus, 64bit, little endian, AMD Ryzen 9 3900 12-Core Processor
CC version: cc (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0

getwd: /home/refaqtor/Sync/Work/SeaArctosLLC/data/sqliter
vmodules: /home/refaqtor/.vmodules
vroot: /home/refaqtor/TOOLS/v
vexe: /home/refaqtor/TOOLS/v/v
vexe mtime: 2021-09-12 19:50:41
is vroot writable: true
is vmodules writable: true
V full version: V 0.2.4 c847152.cd7d482

Git version: git version 2.23.0
Git vroot status: weekly.2021.36-46-gcd7d482c
.git/config present: true
thirdparty/tcc status: thirdparty-linux-amd64 333c14de

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

import encoding.hex as hx

bytes := '010000150107120508d37445a0d7e5c5071980710c64310d9e12043000777369ff0424ab78b91a05164b00e50034003300'
yr := i16((hx.decode(bytes.substr(6,8))?))
println(bytes)
println('yr: $yr')

What did you expect to see?

successful compile, or at least, not 'This is a compiler bug' message

What did you see instead?

==================
/tmp/v/cannotConvertCompilerBug.16348920628964752191.tmp.c:10489: error: cannot convert 'struct array' to 'short'
...
==================
(Use `v -cg` to print the entire error message)

builder error: 
==================
C error. This should never happen.

This is a compiler bug, please report it using `v bug file.v`.

https://github.com/vlang/v/issues/new/choose

You can also use #help on Discord: https://discord.gg/vlang

refaqtor avatar Sep 12 '21 19:09 refaqtor

V should definitely catch this and give a nicer error message.

Question: You're declaring bytes as a string... did you want a byte array instead?

JalonSolov avatar Sep 13 '21 00:09 JalonSolov

Thanks. I get that bytes as a string out of JSON - it is a mix of uint_8/16, and 32 bit floats packed together. Would it make sense to convert the whole thing as byte array first? What would that look like?

This, for example, yr := (hx.decode(bytes.substr(6,8))?)[0] worked well enough for integers.

But, I'm stymied on how to get my floats out... and there may be endian issues, too. Any hints?

refaqtor avatar Sep 13 '21 14:09 refaqtor

That's a big part of the problem of trying to pass binary around. It's the reason so many other formats exist such as JSON, XML, YAML, etc.

How are you getting things packed like that from JSON? JSON files are text format...

JalonSolov avatar Sep 13 '21 16:09 JalonSolov

They come from a satellite data packet from a very low power 8 bit microcontroller. the byte packing is a primary method of compressing that much data into 50 bytes.

On Mon, Sep 13, 2021 at 12:19 PM JalonSolov @.***> wrote:

That's a big part of the problem of trying to pass binary around. It's the reason so many other formats exist such as JSON, XML, YAML, etc.

How are you getting things packed like that from JSON? JSON files are text format...

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub https://github.com/vlang/v/issues/11480#issuecomment-918357187, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABAPYEWKUQMPFQAD5FZERFDUBYQBVANCNFSM5D4NRHYQ . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.

refaqtor avatar Sep 13 '21 16:09 refaqtor

oh, and those 50 bytes are delivered to my https endpoint as just one string item in the JSON.

refaqtor avatar Sep 13 '21 18:09 refaqtor

If those are supposed to be bytes in the string, there is no library function to convert to a byte array, as you have to take each character pair and convert the value to a single byte.

Here's example code I wrote a while ago...

fn char2nibble(b byte) ?byte {
        match b {
                `0`...`9` { return b - 0x30 }
                `A`...`F` { return b - 0x41 + 10 }
                `a`...`f` { return b - 0x61 + 10 }
                else { return error('invalid hex string') }
        }
}

fn hex2byte(hex string) ?[]byte {
        mut my_hex := hex
        mut ba := []byte{}

        if my_hex.len & 1 != 0 {
                my_hex = '0' + my_hex
        }

        for i := 0; i < my_hex.len; i += 2 {
                mut b := char2nibble(my_hex[i]) ?
                ba << (b << 4) + char2nibble(my_hex[i + 1]) ?
        }

        return ba
}

Calling hex2byte(bytes) will give you a byte array, then you should be able to read values out based on the offsets you know, or you could have the byte array as part of a union, with the other part being a struct that described the fields - much easier, and no offsets to worry about.

JalonSolov avatar Sep 13 '21 18:09 JalonSolov

thanks for that. huge! I'm diverted from that project for the moment.
Regardless...... the unhandled error in the v compiler needs the attention on this ticket.

refaqtor avatar Sep 20 '21 19:09 refaqtor