Jump to content
  • Advertisement
Sign in to follow this  
noizex

Passing "this" As Argument ?&in

This topic is 865 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I noticed some weird behavior that I can't figure out. I have function that takes ?&in argument, and as soon as I pass "this" pointer there, it calls the destructor even if I don't do anything in a called function. What it seems to do is to actually create another instance of an object and that's the one that goes into the function, not the original handle. Is there something I don't get about using ?&in ?

 

class Foo

{

   Foo() { print "Foo();\n"; }
   ~Foo() { print "~Foo();\n"; }

 

   void bar() { print("start\n"); call(this); print("stop\n"); }

}

 

Foo f;

f.bar();

 

and the C++ function "call" is:

 

void Call(void* obj, int type_id)

{

    std::cout << "call()" << std::endl;

}

 

 engine->RegisterGlobalFunction("void call(?&in)", asFUNCTION(Call), asCALL_CDECL); assert( r >= 0 );

 

the result? after calling "call(this)" a new object is created, and destroyed as soon as the Call() function exits. So it actually prints this:

 

Foo()

start

Foo()

call()

~Foo()

stop

~Foo()

 

where that first ~Foo() is where new object is created. I guess that if I tried to modify object on C++ side, using that *obj pointer, it would be the object that is gone as soon as the function exits, not the one I think I'm modifying. 

 

So the question is - should it make a "copy"? (I suppose that it actually does a copy of the object, because when I set some foo._value to "X" and default one was empty, the destructed object had it set to "X", indicating a copy rather than new object.

 

And how to prevent this copy? Actually it would be nice if I could decide if I want to pass a copy of an object vs. reference to an object in such case - is it possible with "?" notation, so it would work for any object?

Edited by noizex

Share this post


Link to post
Share on other sites
Advertisement

I've experienced this as well. Unlike handle parameters, ?& in will copy construct, since it isn't defined as a handle. it's like taking the object by reference: Foo& in. That will also copy construct.

 

To avoid this, explicitly convert the this pointer to a handle: @this. That will make Angelscript treat the argument as a handle, and will pass it properly.

Share this post


Link to post
Share on other sites

Looks like "this" is actually an "object value" not "handle", so I tried passing @this and it seems to not create a copy.

 

What confused me there was the "&in" in argument declaration, which to me looks like a reference, and therefore it should pass by reference even if the object passed is not a "pointer"/"handle"? Like in C++ if I pass value object to a function taking the reference, it will implicitly pass it as reference, not as a copy. 

Share this post


Link to post
Share on other sites

I've experienced this as well. Unlike handle parameters, ?& in will copy construct, since it isn't defined as a handle. it's like taking the object by reference: Foo& in. That will also copy construct.

 

To avoid this, explicitly convert the this pointer to a handle: @this. That will make Angelscript treat the argument as a handle, and will pass it properly.

 

Thanks! I managed to find out that @this thing a moment ago.

 

But what if I don't use "?" but declare specific object like MyClass& in - would that copy construct too? Doesn't it defeat the purpose of the reference passing? I must say that I'm using AS since 2011 and I'm still sometimes confused by it's handle/reference/value model :( What difference would be between func(MyClass) and func(MyClass&in)? Or does it only apply to "?&in" specific case? 

Share this post


Link to post
Share on other sites

"& in" will always copy construct, with the exception of copy constructors and (i think) assignment operators. I believe it has to do with the engine's safe reference setting: http://www.angelcode.com/angelscript/sdk/docs/manual/angelscript_8h.html#a53c2e8a74ade77c928316396394ebe0f

 

I think that if you enable asEP_ALLOW_UNSAFE_REFERENCES, it will no longer copy construct them.

Edited by Solokiller

Share this post


Link to post
Share on other sites

Ok, I think I get it now. I thought about it a bit and I wonder - with delayed execution, how do you handle possibility that when passed as argument to delayed function, a handle/reference can be invalid at the time of function execution? It would cause the script to crash probably? I thought about maybe enforcing only primitives or objects passed as weakref that won't hold on to object (this could cause object live forever with a delayed execution looped over, because there will be always argument waiting to be passed to a function, and if it does AddRef, then it will keep the object alive indefinitely?). 

But then I have problems with weak_refs as they're not as easy to use as handle. I can't seem to pass weakref by value, only as weakref<>&in, can't pass it implicitly like  func(myobject) for func(weakref<myobject>&in). There are no examples at all of using weakref as something passed to methods, and from quick prototyping it looks like it can't even find my function that has declaration "void weak_test(weakref<Player>& obj)":

 

desc: call_out: function not found 'void weak_test(weakref<Player>&in)'

 

and in the code:

 

void weak_test(weakref<Player>&in obj)
{
}
 
(and that works for anything else, so I suspect weakref somehow, or decl I try to find is wrong?)
 
PS. does anyone visit #angelscript @ FreeNode? Would be great to be able to chat with people knowing more about Angelscript than me, I'm constantly running into obstacles when trying some non-common things. Googling doesn't help much for these cases, and writing on the forum several times a day feels weird too. Would be great to make that channel a bit more alive and have way to chat with other AS'ers. I joined it and will look there from time to time in my daytime (European time) and sometimes at night.
Edited by noizex

Share this post


Link to post
Share on other sites

My scheduler class copies primitives and value types, and addrefs reference types. After the call finishes value types are destructed and reference types are released.

There should never be any object lifetime issues, but it does cost a bit more memory.

 

I've never used weakref myself, but i think it's intended to be used only as a local, global or member variable.

 

I've never been to FreeNode, but i am on GameSurge every now and then.

Share this post


Link to post
Share on other sites

I hope someone who uses weakrefs could explain this class a bit, because either I'm doing something wrong or it's only intended to be saved as a member of an object and not pass around / return from functions like this:

 

weakref<Foo> function_returning_weakref()
{

     return weakref<Foo>(this);

}

 

weakref<Foo> pFoo = function_returning_weakref();

 

This would be quite helpful, yet whatever I try to do I'm getting "No appropriate opAssign method found in 'weakref' for value assignment". 

Share this post


Link to post
Share on other sites

PS. does anyone visit #angelscript @ FreeNode? Would be great to be able to chat with people knowing more about Angelscript than me, I'm constantly running into obstacles when trying some non-common things. Googling doesn't help much for these cases, and writing on the forum several times a day feels weird too. Would be great to make that channel a bit more alive and have way to chat with other AS'ers. I joined it and will look there from time to time in my daytime (European time) and sometimes at night.

Yep, I'm there every now and then. Haven't had my client on in a long time since I re-installed my OS, but I'll try to be on more.

Share this post


Link to post
Share on other sites

'&in' is there to make it possible to guarantee the life time of the value that the reference refers to. AngelScript will make a copy of the value and store the copy on the local stack to be sure that it stays alive until the function returns. Without the local copy the object could potentially be destroyed while the function is being executed but before the function accesses the reference. In C++ it is the programmers responsibility to make sure the reference is always valid, but in AngelScript I don't put that burden on the programmer.

 

 

The weakref type currently doesn't have a copy constructor or assignment operator. That's why it doesn't allow you to pass this type by value. I'll have this implemented.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!