XSharpPublic icon indicating copy to clipboard operation
XSharpPublic copied to clipboard

In some cases, the compiler cannot determine an appropriate method overload

Open leon-ts opened this issue 2 years ago • 5 comments

When compiling the following example, the compiler reports an error:

FUNCTION Start() AS VOID STRICT
	LOCAL o := TestClass{} AS TestClass
	o:SetItem(0)
	RETURN

CLASS TestClass
	METHOD SetItem(dwItem AS DWORD) AS VOID STRICT
		RETURN
	METHOD SetItem(pItem AS TEST_STRUCT PTR) AS VOID STRICT
		RETURN
END CLASS

VOSTRUCT TEST_STRUCT
	MEMBER dwItem AS DWORD
END VOSTRUCT

Error:

XS0121 The call is ambiguous between the following methods or properties: 'TestClass.SetItem(dword)' and 'TestClass.SetItem(TEST_STRUCT*)'

If you do the same example using functions instead of class methods, then the code compiles without errors. So the problem only occurs when using class methods.

Example project: XSharpBetaTest.zip

Environment: Compiler X# 2.17.0.3 IDE VS 2022

leon-ts avatar Oct 02 '23 09:10 leon-ts

If the literal in the call is changed from 0 to 0U then there is no error.

RobertvanderHulst avatar Feb 13 '24 13:02 RobertvanderHulst

I am not sure, should we consider this fixed with the workaround of using 0U instead of 0, or is it possible to make the compiler detect correctly the intended overload? (low priority obviously)

cpyrgas avatar Sep 25 '24 10:09 cpyrgas

Hello Chris, After I created this issue a year ago, I rethought it after Robert's hint. A pointer is an address (position) in memory whose value is an integer. So passing an integer is appropriate for both methods.

leon-ts avatar Sep 26 '24 07:09 leon-ts

Hi Leonid! Well, this is true for a language like c, but for a high level language like X# or c# technically it isn't really, an integer and a pointer are different types and shouldn't be possible to be used one instead of the other, at least not implicitly. System.Char and enumeration values are also represented by numbers under the hood, but fortunately we cannot simply pass a number to a method accepting those types.

The complication here is that unfortunately VO allowed this (passing a number instead of a pointer without explicit conversion), so we had to allow it in X# also, but I'm sure that this is one of the things that lead to unstable VO applications.

So I'd say let's just keep this on hold for now and in the future reconsider it and make it maybe possible with an option to make the compiler/runtime more strict with things like that.

cpyrgas avatar Sep 26 '24 16:09 cpyrgas

The problem in this case is that the compiler cannot match the literal 0 (of type LONG) with dwItem as DWORD and pItem as TEST_STRUCT PTR. It therefore tries to detect if there is an implicit conversion, and it finds conversions from LONG to DWORD as well as from LONG to PTR. (At this moment) we do not assign a "weight" to these conversions, so we cannot choose which of the two we want to use. Therefore the user either has to add a cast (DWORD) 0 or 0U or (PTR) 0 to help the compiler choose the right overload.

RobertvanderHulst avatar Sep 26 '24 19:09 RobertvanderHulst