V: string.int() behavior change

Created on 26 Nov 2019  路  5Comments  路  Source: vlang/v

V version: 38aba37fe9e67d89674d97ee7a04e15967888efb
OS: macOS 10.15.1

What did you do?
````v
module main

fn main() {
i := "70zzz".int()
println('i: $i')
}
````

What did you expect to see?

i: 70

What did you see instead?

i: 0

I'm not sure what the intended behavior is here, but prior to 5c217b9e61ac47f9c30b785a28af24ae73bf617b calling .int() on a string with trailing non-numbers in it would convert it. So "100zzzz".int() would become 100. Now it becomes 0. I had some code depending on the old behavior so wanted to check that it was an intentional change.

Bug

Most helpful comment

Agreed, and I'm making a PR to do exactly that. However, parse_int and parse_uint are called in other places, and I'll make sure not to break those.

All 5 comments

This may be caused by #2896 I will take a look.

See my NOTEs towards the bottom of this snippet.

// snippet from vlib/strconv/atoi.v in parse_uint (called by parse_int, called by string.int()
        if c == `_` && base0 {
            // underscore_ok already called
            underscores = true
            continue
        }
        else if `0` <= c && c <= `9`   { d = c - `0` }
        else if `a` <= cl && cl <= `z` { d = cl - `a` + 10 }
        else {
            // return error('parse_uint: syntax error $s')
            return u64(0)  // NOTE: This is not likely what is causing the behavior noted in #2901
        }
        if d >= byte(base) {
            // return error('parse_uint: syntax error $s')
            return u64(0) // NOTE: This is likely what is causing the behavior noted in #2901
        }

Need weigh-in here from others... Should this be an error? If yes, I guess we factor parse_int and parse_uint to a call a separate function, and pass in a flag indicating whether to stop or error when a non digit (or invalid digit) is found.

In the case of this issue (#2901) this likely is caused by 'z' being valid in base 36, but not base 10... (obviously...)

I think that 70zzz should be 70 in base 10.

The first invalid character should stop the scanning from * left to right *, but the accumulated value should be returned.

Agreed, and I'm making a PR to do exactly that. However, parse_int and parse_uint are called in other places, and I'll make sure not to break those.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

lobotony picture lobotony  路  3Comments

vtereshkov picture vtereshkov  路  3Comments

ArcDrake picture ArcDrake  路  3Comments

radare picture radare  路  3Comments

radare picture radare  路  3Comments