How to fix error 177 ???

General FreeBASIC programming questions.
mrminecrafttnt
Posts: 131
Joined: Feb 11, 2013 12:23

How to fix error 177 ???

Post by mrminecrafttnt »

Hi! I am writing actually on an new Inventory Engine.
But i stopped at error 177. ?? What does this means:
RETURN mixed with 'FUNCTION =' or EXIT FUNCTION (using both styles together is unsupported when returning objects with constructors), found 'ObjectData' in 'return ObjectData(id)'
Thanks for help. :)

Code: Select all

'Inventory Engine

type InventoryObjectData
    Objectname as string
    ObjAmount as integer
end type

type Inventory
    ObjectData(any) as InventoryObjectData
    declare sub addObj (ObjName as string, amount as integer)
    declare sub setObj (ObjName as string, amount as integer)
    declare function search_id (ObjName as string) as integer
    declare function getObj (ObjName as string) as InventoryObjectData
end type

function Inventory.search_id (Objname as string) as integer
    for i as integer = lbound(ObjectData) to ubound(ObjectData)
        if ObjectData(i).Objectname = Objname then return i
    next
    return -1
end function

sub Inventory.setObj (Objname as string,amount as integer)
    dim as integer id = search_id(Objname)
    if id = -1 then
        print "Object not found"
        exit sub
    else
        ObjectData(id).Objamount = amount
    end if
end sub

function Inventory.getObj(ObjName as string) as InventoryObjectData
    dim as integer id = search_id(ObjName)
    if id = -1 then
        print "Object not found"
        exit function
    else
        return ObjectData(id)
    end if
end function

    

sub Inventory.addObj (ObjName as string,amount as integer)
    
        if search_id(ObjName) > -1 then
            Print "Object allready exists"
            exit sub
        end if
    
    redim ObjectData(ubound(ObjectData)+1)
    with ObjectData(ubound(ObjectData))
        .Objectname = ObjName
        .ObjAmount = amount
    end with
    Print "Object added"
end sub

            
fxm
Moderator
Posts: 12081
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: How to fix error 177 ???

Post by fxm »

Code: Select all

function Inventory.getObj(ObjName as string) as InventoryObjectData
    dim as integer id = search_id(ObjName)
    if id = -1 then
        print "Object not found"
'        exit function
    else
        return ObjectData(id)
    end if
end function
badidea
Posts: 2586
Joined: May 24, 2007 22:10
Location: The Netherlands

Re: How to fix error 177 ???

Post by badidea »

I don't know exactly, but this seems to work:

Code: Select all

function Inventory.getObj(ObjName as string) as InventoryObjectData
    dim as integer id = search_id(ObjName)
    if id = -1 then
        print "Object not found"
        'exit function
        return type<InventoryObjectData>()
    else
        return ObjectData(id)
    end if
end function
I see that my 'return type<InventoryObjectData>()' can be left out. Same result?
fxm
Moderator
Posts: 12081
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: How to fix error 177 ???

Post by fxm »

badidea wrote:I see that my 'return type<InventoryObjectData>()' can be left out. Same result?
No, your code is safer.
See my post: viewtopic.php?p=227137#p227137
dodicat
Posts: 7976
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: How to fix error 177 ???

Post by dodicat »

I think that this was discussed a while back.
There should always be a return value, especially with udt's.
Simplified example.
SORRY MISSED YOUR POST fxm

Code: Select all

type udt1
    s as string
    i as integer
end type

type udt2
    a(any) as udt1
    declare function getthis(as string="") as udt1
end type

function udt2.getthis(g as string) as udt1
    dim as integer id =ubound(a)
    if id=-1 then
        print "not found"
        return type<udt1> ''comment out
    else
        return a(id)
        end if
end function


dim as udt2 x
dim as udt1 y=x.getthis()
print y.s
print y.i

sleep

      
Munair
Posts: 1286
Joined: Oct 19, 2017 15:00
Location: Netherlands
Contact:

Re: How to fix error 177 ???

Post by Munair »

Is there any advantage of returning an explicit temporary type?

Code: Select all

function Inventory.getObj(ObjName as string) as InventoryObjectData
    dim as integer id = search_id(ObjName)
    if id = -1 then
        print "Object not found"
        return InventoryObjectData()
    end if
    return ObjectData(id)
end function
fxm
Moderator
Posts: 12081
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: How to fix error 177 ???

Post by fxm »

'InventoryObjectData()' is also a temporary instance.
(the two syntaxes are equivalent in this case)
Munair
Posts: 1286
Joined: Oct 19, 2017 15:00
Location: Netherlands
Contact:

Re: How to fix error 177 ???

Post by Munair »

So in this case the type() syntax is also equivalent:

Code: Select all

function Inventory.getObj(ObjName as string) as InventoryObjectData
    dim as integer id = search_id(ObjName)
    if id = -1 then
        print "Object not found"
        return type()
    end if
    return ObjectData(id)
end function
fxm
Moderator
Posts: 12081
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: How to fix error 177 ???

Post by fxm »

Yes.
The implicit typename is the one specified as return in the function declaration.
badidea
Posts: 2586
Joined: May 24, 2007 22:10
Location: The Netherlands

Re: How to fix error 177 ???

Post by badidea »

An alternative:

Code: Select all

function Inventory.getObj(ObjName as string) as InventoryObjectData
    dim as integer id = search_id(ObjName)
    dim as InventoryObjectData IOD
    if id = -1 then
        print "Object not found"
    else
        IOD = ObjectData(id)
    end if 
    return IOD
end function
Munair
Posts: 1286
Joined: Oct 19, 2017 15:00
Location: Netherlands
Contact:

Re: How to fix error 177 ???

Post by Munair »

Recently I proposed the support of 'null objects' to avoid any constructor call if the creation of an instance is not desired when a condition is (not) met:

Code: Select all

type TT extends object
	b as boolean
	declare constructor()
end type

constructor TT()
	print "TT called"
end constructor

function SomeTT(byval b as boolean = false) byref as TT
	dim byref t as TT = *cptr(TT ptr, 0)
	if b then
		@t = @TT()
		t.b = b
	end if
	return t
end function

print "t = TT(false)"
dim byref t as TT = SomeTT()

print "t = TT(true)"
@t = @(SomeTT(true))
print t.b
sleep:end
While FB allows this for individual objects (byref syntax could be cleaned up), currently objects within objects cannot have a null reference.
fxm
Moderator
Posts: 12081
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: How to fix error 177 ???

Post by fxm »

Your above code is not safe because 'TT()' is a local instance in the function body.

Similar example to highlight the bug:

Code: Select all

type TT extends object
   s as string
   declare constructor()
end type

constructor TT()
   print "TT called"
end constructor

function SomeTT(byval b as boolean = false) byref as TT
   dim byref t as TT = *cptr(TT ptr, 0)
   if b then
      @t = @TT()
      t.s = "Hello"
   end if
   return t
end function

print "t = TT(false)"
dim byref t as TT = SomeTT()
print "t = TT(true)"
@t = @(SomeTT(true))
print t.s

sleep
Now the safe version:

Code: Select all

type TT extends object
   s as string
   declare constructor()
end type

constructor TT()
   print "TT called"
end constructor

function SomeTT(byval b as boolean = false) byref as TT
   dim byref t as TT = *cptr(TT ptr, 0)
   if b then
      @t = new TT
      t.s = "Hello"
   end if
   return t
end function

print "t = TT(false)"
dim byref t as TT = SomeTT()
print "t = TT(true)"
@t = @(SomeTT(true))
print t.s

delete @t
sleep
Munair
Posts: 1286
Joined: Oct 19, 2017 15:00
Location: Netherlands
Contact:

Re: How to fix error 177 ???

Post by Munair »

@fxm, your example code to highlight the bug compiles and runs just fine on Linux x64. Here is the console output:
t = TT(false)
t = TT(true)
TT called
Hello
Munair
Posts: 1286
Joined: Oct 19, 2017 15:00
Location: Netherlands
Contact:

Re: How to fix error 177 ???

Post by Munair »

fxm wrote:Your above code is not safe because 'TT()' is a local instance in the function body.
Isn't the return byref supposed to keep the reference after the function call?
fxm
Moderator
Posts: 12081
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: How to fix error 177 ???

Post by fxm »

In FreeBASIC, a reference is in fact an internal pointer (created by the compiler) which is implicitly dereferenced when user want to access the reference.
In the bugged code, the internal pointer points to a local instance (which is so destroyed when returning from the function).

For more information on references, see my article How FB supports References (pass and return byref, byref variables), and How to Use them
Post Reply