Open GWRon opened 5 years ago
First off: Yes, t.PrintOut(0)
failing looks like a bug. It should choose the Int
overload without complaints.
The error message you're getting would only be legitimate if you only had a Byte
overload and Short
overload, but no Int
overload.
I understand the "problem" behind it - how should the compiler know about the value given to the function. Is a "0" an integer or an "byte"?
That's very simple, actually: 0
is always an Int
.
A "null" can be an empty string, a non existing object, or simply a "0".
During compilation BCC knows if there is a "", an 0 or a null written, so it should be able to change preference: empty strings prefer string-overloads, null prefers objects and a number
bcc does do that, but it doesn't involve any special treatment in regard to overloading. The way it works (or should work, if it isn't currently bugged) is this:
Null
has a unique type, the "null type". You can't really do anything with that type at all, except convert it to another type. It can be implicitly and explicitly converted to any other type*, and when doing so, it turns into the default value for that type.
This is why t.PrintOut(Null)
fails - Null
can turn into any other type, so it fits every overload of PrintOut
equally well and thus the call is ambiguous.
As for other literals, including the ones you brought up:
Object(Null)
is an explicit conversion, so its type is Object
and it chooses the Object
overload""
is synonymous with String(Null)
(so its type is String
etc.)0
is synonymous with 0:Int
and with Int(Null)
0.0
is synonymous with 0:Float
and with Float(Null)
0:Byte
is synonymous with Byte(0)
and with Byte(Null)
Note that all this is actually unrelated to overloading: 0
is always an Int, and ""
is always the same as String(Null)
. But due to this, a t.PrintOut(0)
is supposed to prefer an Int
overload and t.PrintOut("")
is supposed to prefer a String
overload. (And by "prefer", I mean "choose it without a warning or error".) If it doesn't do that, then that is indeed a bug.
(* except intrinsics and structs currently... we should probably fix that sometime)
That's actually very simple: 0 is always an Int.
Why is this? Why not the smallest possible numeric type...or the biggest? Because in nonstrict numbers would be int by default too?
Anyways and as always: thanks for your elaborative answer...albeit they are often too complex to chew in one piece.
Why is this? Why not the smallest possible numeric type...or the biggest?
Because Int
was chosen as being generally the most useful one.
Why not smaller? Because Byte
or Short
would restrict you to a smaller set of numbers you can work with, and the lesser amount of RAM they take up doesn't normally matter.
Why not larger? Because Int
, being 32 bit large, is efficient for calculations on a 32 bit computer. Long
, which is 64 bit, works fine on a 64 bit computer, but is slower on a 32 bit one.
Several other languages (for example, Java) also use an 32-bit-sized int
type for this reason.
There are however also languages like C, where int
is whatever the compiler feels like (which means it can choose the most efficient size for the target system, at the expense of portability).
So it does not choose by "what suits best" but by "what is the most common".
Aside of that question it seems the second point of the issue (field.set()) is the one being potentially borked then(?).
If there is a TField.Set:Int(obj:Object,value:Int)
overload, then field.Set(obj, 0)
should always choose that, no matter which other overloads exist for the second parameter.
Since you get the same kind of error from your TTest
example though, it apparently has nothing to do with TField.Set
in particular, it's just the overload resolution currently not working right.
The latest brl.mod/reflection.mod-change introduced some overloading - leading to issues in my code as the overloading ("of course"?) cannot identify what method to use.
First fail results in
Compile Error: Unable to determine overload to use: Method TTest.PrintOut(v:Int) or Method TTest.PrintOut(v:Byte).
The "odd" print is using the "int" overloaded method. When using the brl.reflection functionalityfield.Set(obj, 0)
it results inCompile Error: Unable to determine overload to use: Method TField.Set:Int(obj:Object,value:Byte) or Method TField.Set:Int(obj:Object,value:Short)
.I understand the "problem" behind it - how should the compiler know about the value given to the function. Is a "0" an integer or an "byte"? A "null" can be an empty string, a non existing object, or simply a "0".
During compilation BCC knows if there is a
""
, an0
or anull
written, so it should be able to change preference: empty strings prefer string-overloads,null
prefers objects and a number ... hmm, it could be the lowest possible number (0-255 = byte - and so on) but this hmm... is tricky. Maybe BCC should output a warning for ambiguity then. Or it should print a hint next to the current error message. Something stating that a number can be "defined" by appending the type (0:byte
).What are your thoughts on this?