Overloading and subs with default parameters

Coding and general discussion relating to the compiler

Moderators: David Barker, Jerry Messina

Post Reply
SHughes_Fusion
Posts: 219
Joined: Wed Sep 11, 2013 1:27 pm
Location: Chesterfield

Overloading and subs with default parameters

Post by SHughes_Fusion » Wed Oct 19, 2016 4:03 pm

Does the compiler support overloading and pre-loading of sub parameters at the same time?

I've tried declaring a series of subs which load different data types in to a log, with the data value pre-set to zero. However, the compiler complains that it can't determine which one to use. It worked fine before I decided to add the ability to store more than one data type in the log so is this a compiler limitation or am I doing something wrong?

The sub declarations are of this form, for bytes, words, integers and floats.

Code: Select all

Sub AddToLog(pEntryType As Byte, pEntryData As Float = 0.0)

Jerry Messina
Swordfish Developer
Posts: 1469
Joined: Fri Jan 30, 2009 6:27 pm
Location: US

Re: Overloading and subs with default parameters

Post by Jerry Messina » Wed Oct 19, 2016 4:50 pm

If I follow, you have something like

Code: Select all

sub AddToLog(pEntryType As Byte, pEntryData As Float = 0.0)
sub AddToLog(pEntryType As Byte, pEntryData As Byte = 0)
sub AddToLog(pEntryType As Byte, pEntryData As Word = 0)

dim b as byte
AddToLog(b)
and it's complaining that it can't resolve the ambiguous call.

I can't resolve it either. I don't think it's a compiler limitation as much as a logical one.
Looking at the above, which one should it call?

If you specify the second parameter then it has enough information, but that sort of defeats the purpose of the default initializer.

User avatar
octal
Registered User
Registered User
Posts: 586
Joined: Thu Jan 11, 2007 12:49 pm
Location: Paris IDF
Contact:

Re: Overloading and subs with default parameters

Post by octal » Wed Oct 19, 2016 7:18 pm

Read the Swordfish Help file about subroutines overloading.
When you do overloading, you must **not** create, in anyway, an ambiguous situation.
When you call your routine with only one parameter, the compiler (humans also) cannot determine your intentions.

Check help file, it has extensive explanation, and last example in it reproduces absolutely your situation

From SF help file:
Overloading

Overloading enables you to have multiple subroutines and functions in the same scope that share the same name. The compiler will select the most appropriate routine to call, based on its signature. A subroutine or function signature is constructed by using the number of formal parameters and also the type of each parameter. An overloaded routine must therefore have a unique combination of parameters, so that the compiler can identify which routine to call during compilation. For example,

function Multiply(pValueA, pValueB as byte) as word
Result = pValueA * pValueB
end function

function Multiply(pValueA, pValueB as byte) as float
Result = pValueA * pValueB
end function

will generate an error because the overloaded function signatures are identical. That is, they both have two parameters each of type byte. It is important to note that the compiler does not use function return types as part of the signature, only parameters The previous problem can be corrected by overloading the function with a unique parameter signature, like this,

function Multiply(pValueA, pValueB as byte) as word
Result = pValueA * pValueB
end function

function Multiply(pValueA, pValueB as float) as float
Result = pValueA * pValueB
end function

dim Result as word
Result = Multiply(10,20)

In this example, the first overloaded function is called because the parameter arguments are of type byte. The compiler will try and invoke the routine whose parameters have the smallest range that will accommodate the arguments in the call. For example, if the call to Multiply() is made with the following arguments,

Result = Multiply(-10,20)

then the second function will be called, because the floating point parameter is the only one that can accommodate a value of -10.

If the type of the value to be returned is to be the only unique way of identifying an overloaded routine a Sub should be used and the result of the routine passed byRef in the parameters. For example:

sub MySub(byref pValue As Byte)

end sub

Sub MySub(byref pValue As Word)

end sub


If any parameters are assigned a constant in an overloaded routine, care should be taken to ensure you don't inadvertently create a situation where a routine cannot be called, for example,

sub MySub(pValueA as byte, pValueB as word = 0)

end sub

sub MySub(pValueA as byte)

end sub

MySub(10)

In this example, the compiler cannot determine if the first or second overloaded routine should be called, because the parameter arguments are ambiguous.

SHughes_Fusion
Posts: 219
Joined: Wed Sep 11, 2013 1:27 pm
Location: Chesterfield

Re: Overloading and subs with default parameters

Post by SHughes_Fusion » Thu Oct 20, 2016 6:55 am

Thanks both, so in other words I can't do what I am trying to do and even for events which don't need data I still need to pass a value so SF can decide which to use? I guess the ideal solution here would be if you could specify a 'default' one to call in these cases - for what I'm doing, it doesn't actually matter which is called when I don't have data to pass.

For that reason I'd not actually realised it was ambiguous but looking back it is. And yes, I had read the help file, I just didn't spot the relevance of that example as it shows two clearly different subs.

So I guess either I need to pass data even when not necessary or create a separate sub for data-less events which breaks up the continuity of the code but means not passing redundant data.

User avatar
octal
Registered User
Registered User
Posts: 586
Joined: Thu Jan 11, 2007 12:49 pm
Location: Paris IDF
Contact:

Re: Overloading and subs with default parameters

Post by octal » Thu Oct 20, 2016 9:35 am

I don't know what you want to do, but (from my own guess), you better use COMPOUND subroutines. Check help file and how SF use them in the various libraries like USART or SPI to write read various types of data using overloaded subs.

Jerry Messina
Swordfish Developer
Posts: 1469
Joined: Fri Jan 30, 2009 6:27 pm
Location: US

Re: Overloading and subs with default parameters

Post by Jerry Messina » Thu Oct 20, 2016 9:52 am

and even for events which don't need data I still need to pass a value so SF can decide which to use?
I think if you remove the default initializer you can get what you want...

Code: Select all

sub AddToLog(pEntryType As Byte)
sub AddToLog(pEntryType As Byte, pEntryData As Float)
sub AddToLog(pEntryType As Byte, pEntryData As Byte)
sub AddToLog(pEntryType As Byte, pEntryData As Word)
That seems to make sense to me... if you want to log data then pass it data to log, otherwise just log the entry.

The default initializer probably doesn't really help you out anyway in this instance... it's not like it produces less code or something.

SHughes_Fusion
Posts: 219
Joined: Wed Sep 11, 2013 1:27 pm
Location: Chesterfield

Re: Overloading and subs with default parameters

Post by SHughes_Fusion » Thu Oct 20, 2016 10:05 am

Thanks, Jerry, that works.

I think I actually ended up getting confused by the example in the help file as that is pretty much what I was planning to do but got the impression it wasn't possible from that example so tried initialising to zero instead.

You are right that in this case I don't need to initialise - if no data is passed then I just log the event but if data is passed I log it.

Post Reply