How to fix error 177 ???

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

How to fix error 177 ???

Postby mrminecrafttnt » Dec 06, 2018 21:56

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
Posts: 8516
Joined: Apr 22, 2009 12:46
Location: Paris (suburbs), FRANCE

Re: How to fix error 177 ???

Postby fxm » Dec 06, 2018 22:02

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: 1054
Joined: May 24, 2007 22:10
Location: The Netherlands

Re: How to fix error 177 ???

Postby badidea » Dec 06, 2018 22:11

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
Posts: 8516
Joined: Apr 22, 2009 12:46
Location: Paris (suburbs), FRANCE

Re: How to fix error 177 ???

Postby fxm » Dec 06, 2018 22:31

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: 5332
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: How to fix error 177 ???

Postby dodicat » Dec 06, 2018 22:42

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: 802
Joined: Oct 19, 2017 15:00
Location: 't Zand, NL
Contact:

Re: How to fix error 177 ???

Postby Munair » Dec 06, 2018 22:48

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
Posts: 8516
Joined: Apr 22, 2009 12:46
Location: Paris (suburbs), FRANCE

Re: How to fix error 177 ???

Postby fxm » Dec 07, 2018 6:03

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

Re: How to fix error 177 ???

Postby Munair » Dec 07, 2018 6:21

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
Posts: 8516
Joined: Apr 22, 2009 12:46
Location: Paris (suburbs), FRANCE

Re: How to fix error 177 ???

Postby fxm » Dec 07, 2018 6:36

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

Re: How to fix error 177 ???

Postby badidea » Dec 07, 2018 9:27

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: 802
Joined: Oct 19, 2017 15:00
Location: 't Zand, NL
Contact:

Re: How to fix error 177 ???

Postby Munair » Dec 07, 2018 10:16

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
Posts: 8516
Joined: Apr 22, 2009 12:46
Location: Paris (suburbs), FRANCE

Re: How to fix error 177 ???

Postby fxm » Dec 07, 2018 10:41

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: 802
Joined: Oct 19, 2017 15:00
Location: 't Zand, NL
Contact:

Re: How to fix error 177 ???

Postby Munair » Dec 07, 2018 10:52

@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: 802
Joined: Oct 19, 2017 15:00
Location: 't Zand, NL
Contact:

Re: How to fix error 177 ???

Postby Munair » Dec 07, 2018 11:09

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
Posts: 8516
Joined: Apr 22, 2009 12:46
Location: Paris (suburbs), FRANCE

Re: How to fix error 177 ???

Postby fxm » Dec 07, 2018 12:08

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

Return to “General”

Who is online

Users browsing this forum: No registered users and 3 guests