View unanswered posts | View active topics It is currently Thu Nov 28, 2024 8:32 am



Reply to topic  [ 8 posts ] 
 ERROR: call of overloaded function '?(nil) is ambiguous 
Author Message

Joined: Mon Jul 11, 2016 5:06 am
Posts: 8
Reply with quote
Post ERROR: call of overloaded function '?(nil) is ambiguous
I'd like a bit more clarification as to what causes this error I keep encountering:

Code:
ERROR: call of overloaded function '[various nonsense here](nil) is ambiguous
none of the overloads have a best conversion:[same various nonsense here](Entity*)
[same various nonsense here](const Entity*)


From my understanding using certain casting functions such as ToActor() and then saving the result to a variable will do it. My questions is, which functions work and which ones do not? Is ToHeldDevice() or ToAttachable() too ambiguous? Do they only work under certain conditions? Some vanilla code in Base.rte does use ToActor() and save to a variable.

Sorry I do not have any specific code to show, I am trying to fix up mods made by various people, especially very old mods. The source of this error seems impossible to figure out without knowing more about the nature of it.


Fri Apr 21, 2017 4:34 am
Profile

Joined: Fri Sep 10, 2010 1:48 am
Posts: 666
Location: Halifax, Canada
Reply with quote
Post Re: ERROR: call of overloaded function '?(nil) is ambiguous
When you say nonsense here do you mean gibberish characters? I've had those show up in a few situations in the past, though I don't honestly remember the causes or my solutions.

As a general rule, if you're running into issues but you don't know where, I'd say put in frequent prints to see where the point of failure is, then post back with that knowledge. Without more information or code, you might not have much luck finding someone to help you. Of course, it's possible someone's run into this before and remembers the solution.
Also, putting the exact error message is probably a good thing even if it's gibberish. ConsoleMan:SaveAllText("Filename Here") will save the console text, and CC also saves it on exit.


Fri Apr 21, 2017 5:26 am
Profile

Joined: Mon Jul 11, 2016 5:06 am
Posts: 8
Reply with quote
Post Re: ERROR: call of overloaded function '?(nil) is ambiguous
Print statements everywhere were my go-to solution until I got tired of that and came here in search of answers lol. And yes, I do mean the one or couple of gibberish characters. Most of the time it's non-printable ones so they won't even show up here, but here's one a bit more "verbose" than most, one of many just taken from the last run.

Code:
ERROR: call of overloaded function 'xֻ5\(nil) is ambiguous
none of the overloads have a best conversion:xֻ5\(Entity*)
xֻ5\(const Entity*)


Many, many instances of these in a sequence, usually.

It's pretty much beyond doubt these are caused by the casting functions like ToActor(), etc. Although if there exists another cause that's unknown. The one time it's been brought up here along with an answer, the solution pointed out by Cave Cricket was to swap ToActor() to ToAHuman() and I'd just like to know why, and how this works. My solution thus far was to eliminate all instances of saving the result of ToActor() to a variable wherever possible.

But then I see something like

Code:
--Cycle through all MOs and see which is the closest.
for i = 1, MovableMan:GetMOIDCount() - 1 do
   part = MovableMan:GetMOFromID(i)
   if part and part.ClassName ~= "MOSParticle" and part.ClassName ~= "MOPixel" and part.ClassName ~= "HDFirearm" and part.ClassName ~= "HeldDevice" then
      part = ToMovableObject(part)
      dist = SceneMan:ShortestDistance(self.Pos, part.Pos, false).Magnitude
      if dist < curdist then
         curdist = dist
         chosenpart = part
      end
   end
end

--If a part was found in the range, find its parent actor and burn it.
if chosenpart then
    local MO = MovableMan:GetMOFromID(chosenpart.RootID)
    if MovableMan:IsActor(MO) then
        MO = ToActor(MO)
        MO.Health = MO.Health - 100 / MO.Mass   -- reduce damage to heavy actors
    end
end


in Base.rte/Effects/Pyro/GroundFlame.lua (note use of ToMovableObject and ToActor), and assuming that's correct now I wonder why it's safe to use here (or why ToMovableObject was necessary at all) but not elsewhere. Also, what to do about ToAEmitter, ToAttachable, ToHeldDevice, and others.

My hope is that someone here might have more info on these conversion functions since they're not mentioned anywhere on the wiki.


Fri Apr 21, 2017 6:53 am
Profile

Joined: Fri Sep 10, 2010 1:48 am
Posts: 666
Location: Halifax, Canada
Reply with quote
Post Re: ERROR: call of overloaded function '?(nil) is ambiguous
Alright, so I obviously haven't seen the game's source so I could be wrong, but here's my interpretation of it.
The reason you're running into these problems is cause the code has several ToActor methods, which take in different objects (or more specifically, probably object pointers) - one takes in AHuman, one takes in MovableObject, etc. They look the same from lua cause of method overloading, so you just end up calling the relevant for your input without really knowing how it works. So the issue is that it doesn't know exactly which one to use because somehow the input confuses it, and since lua doesn't have strong typing, you can't tell it which to use. This may also be an edge case bug in the game's lua binding, I've seen the const Object* vs Object* problem before and I seem to recall it being a bug that needed to be solved.
Note that saving it to a variable is entirely irrelevant (or should be), since what matters is the problematic method call - once it returns the value to the lua script it doesn't matter what you do with it, or probably shouldn't unless something's done wrong in the game's lua binding.

As for why ToAHuman works, my guess is that there aren't any overloads, or maybe there's only a couple - one for Actor and one for MovableObject, so it doesn't run into these problems of not being able to find the right method.
So, it's still hard for me to say how you should solve the problem - the cheap and easy way is to replace the ToActors with ToAHumans where possible, which'd probably solve most of your problems, but the deeper solution would be to look at what's being ToActored in each case and make sure it's already something reasonable, like a MovableObject or an MOSprite or whatever.

Finally, don't always assume that the base game scripts are perfect, everyone can make mistakes or be careless. Looking at your example I don't think there's any reason at all for that ToMovableObject(part) cast, since part should already be a MovableObject as GetMOFromID should return that (see wiki link here). However, it could be a bit of CC lua pointer mess making it necessary to convert the MO pointer to an MO, I can't say for sure without testing it out. Either way, an easy way to see if it's needed would be to delete the line and see if it breaks.


Fri Apr 21, 2017 8:07 pm
Profile

Joined: Mon Jul 11, 2016 5:06 am
Posts: 8
Reply with quote
Post Re: ERROR: call of overloaded function '?(nil) is ambiguous
I think I see what you're saying. I can't say I know the specifics of how typing works in Lua, I just know what I've picked up in practice. I thought there might be something going on behind the scenes with Lua such that when you save something to a variable type suddenly strongly matters, since it internally keeps track of it or something, and Actor is just a parent of several possible subclasses. I don't know, that was just my reasoning.

Every time I encounter the error I go through all suspect code and do this - remove ToMovableObject calls in situations as above, change ToActor calls to more specific ToAHuman or ToACrab, and for the others call the cast on every instance of a variable rather than saving the cast version just once. This fixes it in the end, I just don't know which of these are necessary. I guess I'll take the time to do it one by one next time.


Fri Apr 21, 2017 10:33 pm
Profile

Joined: Fri Sep 10, 2010 1:48 am
Posts: 666
Location: Halifax, Canada
Reply with quote
Post Re: ERROR: call of overloaded function '?(nil) is ambiguous
Nah lua is weakly typed (look here and here) so variables carry their type. Any game objects are kept as userdata type, which I guess is serialized and deserialized in some way to communicate between scripts and the lua interpreter - I don't know much about this set of stuff so I can't really say. But yeah, there should be no way for saving to cause problems, since it's all just serializable userdata as far as I know.

And yeah, do things one at a time to see where the point of failure is, if you've got the time, try every possible iteration of changes to see what works and doesn't so you have a better idea of things. I'd say start with the ToMovableObject calls, most of the time they're probably not necessary anyway, since most things you're working with will already be a MovableObject or some child of it. Next would be ToActor, which can still be problematic, though probably less so. If that doesn't work and you do have to remove all variable assignments I'll be quite surprised, but please post here and let people know, that'd be interesting to find out about.


Fri Apr 21, 2017 11:16 pm
Profile

Joined: Mon Jul 11, 2016 5:06 am
Posts: 8
Reply with quote
Post Re: ERROR: call of overloaded function '?(nil) is ambiguous
After more debugging I think it's safe to say that the assignment does not matter at all. To anyone encountering this error, just try to be as specific as possible with the casting- e.g., ToAHuman instead of ToActor. If your code is to operate on Actors of different types, or you're just unsure, check the type by using a block like this encountered in the base AI code:

Code:
if FoundMO.ClassName == "AHuman" then
   FoundMO = ToAHuman(FoundMO)
elseif FoundMO.ClassName == "ACrab" then
   FoundMO = ToACrab(FoundMO)
elseif FoundMO.ClassName == "ACRocket" then
   FoundMO = ToACRocket(FoundMO)
elseif FoundMO.ClassName == "ACDropShip" then
   FoundMO = ToACDropShip(FoundMO)
elseif FoundMO.ClassName == "ADoor" then
   FoundMO = ToADoor(FoundMO)
elseif FoundMO.ClassName == "Actor" then
   FoundMO = ToActor(FoundMO)
else
   FoundMO = nil
end


Same can be done with ToHeldDevice, ToHDFirearm, ToTDExplosive, etc. Do not use ToMovableObject cast when iterating through all MOs, and in general use only casting when necessary, not "just to be sure". These should solve any errors related to this, hope this helps.


Mon May 08, 2017 9:13 pm
Profile

Joined: Fri Sep 10, 2010 1:48 am
Posts: 666
Location: Halifax, Canada
Reply with quote
Post Re: ERROR: call of overloaded function '?(nil) is ambiguous
Good on you for going through the effort of ascertaining that, it makes sense it wouldn't.

Also, bit of a side-note but I was thinking it could be compressed slightly if it's put in a table, though the end result is only a bit shorter and probably a little less clear to read. Still, here it is if anyone finds all that if-else too unwieldy:


Tue May 09, 2017 12:33 am
Profile
Display posts from previous:  Sort by  
Reply to topic   [ 8 posts ] 

Who is online

Users browsing this forum: No registered users


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group.
Designed by STSoftware for PTF.
[ Time : 0.063s | 13 Queries | GZIP : Off ]