From a15559ada48b331d1a951710478c46046c863340 Mon Sep 17 00:00:00 2001 From: Eric Myhre Date: Mon, 2 Sep 2019 11:10:32 +0200 Subject: [PATCH] Unmarshalling without type info prefers int64. Similar changes were commit 36d31e7716ec3a8517035447a57dde1d88cd528e; but there, we used 'int', with the reasoning "Plainer is better." I've since received complaints about this: that on 32-bit architectures this will result in different behavior than on 64-bit, and that it may be lossy on 32-bit. Since the only downside of using int64, as far as I know, is that it takes a few more characters on the source side -- 'int' is already uses 64-bits of space on a 64-bit architecture anyway -- I guess I'll concede that it might as well be the default. As before, it's important to address this at all because otherwise we would experience some odd behaviors in that the CBOR unmarshal and JSON unmarshal would behave differently when targeting an empty interface: JSON would yield int64, while CBOR would yield *uint64*, due to CBOR's Interesting (ahem) Opinions about signedness of numbers. And as before, remember: if unmarshalling into a concrete type that uses some other numeric type like `uint64`, etc, those unmarshallings do not pass through this cast and are not affected by this change. --- bench/framework_test.go | 2 +- bench/map_test.go | 8 ++++---- obj/unmarshalBuiltins.go | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/bench/framework_test.go b/bench/framework_test.go index c398c87..0427a99 100644 --- a/bench/framework_test.go +++ b/bench/framework_test.go @@ -119,7 +119,7 @@ func fixFloatsToInts(in interface{}) interface{} { } return out case float64: - return int(in2) + return int64(in2) default: return in } diff --git a/bench/map_test.go b/bench/map_test.go index 9bcb88c..f9f626d 100644 --- a/bench/map_test.go +++ b/bench/map_test.go @@ -24,14 +24,14 @@ var fixture_mapAlpha = map[string]interface{}{ }, "C": map[string]interface{}{ "N": "n", - "M": 13, + "M": int64(13), }, "C2": map[string]interface{}{ "N": "n2", - "M": 14, + "M": int64(14), }, - "X": 1, - "Y": 2, + "X": int64(1), + "Y": int64(2), "Z": "3", "W": "4", } diff --git a/obj/unmarshalBuiltins.go b/obj/unmarshalBuiltins.go index ae79e25..c8a6528 100644 --- a/obj/unmarshalBuiltins.go +++ b/obj/unmarshalBuiltins.go @@ -159,9 +159,9 @@ func (mach *unmarshalMachinePrimitive) Step(_ *Unmarshaller, _ *unmarshalSlab, t case TBool: mach.rv.Set(reflect.ValueOf(tok.Bool)) case TInt: - mach.rv.Set(reflect.ValueOf(int(tok.Int))) // Unmarshalling with no particular type info should default to using plain 'int' whenever viable. + mach.rv.Set(reflect.ValueOf(int64(tok.Int))) // Unmarshalling with no particular target type info should consistently map into 'int64' to avoid passing on vagueries of codecs around numeric types. case TUint: - mach.rv.Set(reflect.ValueOf(int(tok.Uint))) // Unmarshalling with no particular type info should default to using plain 'int' whenever viable. + mach.rv.Set(reflect.ValueOf(int64(tok.Uint))) // Unmarshalling with no particular target type info should consistently map into 'int64' to avoid passing on vagueries of codecs around numeric types. case TFloat64: mach.rv.Set(reflect.ValueOf(tok.Float64)) case TNull: