Advertisement

References as return values: assertions and crashes

Started by April 10, 2009 11:14 PM
5 comments, last by WitchLord 15 years, 7 months ago
Hello, I'm a newbie to AngelScript, so maybe there is something that I simply don't understand or don't know. The problem is: if I use references as return values, no matter in what context, compiler keeps crashing during execution or during compilation. I come up with this code to reproduce crash (with AngelScript compiled from recent SVN revision): string& SomeFunc() { return ""; } void main() { string s = SomeFunc(); } And with somewhat more verbose code to reproduce assertion: // Output: // My class constructed // My class constructed with param: 42 // Assertion failed: other.objType->DerivesFrom(objType), file ..\..\source\as_scriptstruct.cpp, line 438 class MyClass { int id; MyClass() { print("My class constructed\n"); } MyClass(int arg) { id = arg; print("My class constructed with param: " + id + "\n"); } } MyClass& SomeFunc() { return MyClass(42); } void main() { MyClass m = SomeFunc(); }
You need to understand how the following is processed in order to know why it's crashing:

MyClass& SomeFunc(){    return MyClass(42);}


The problem here is that MyClass(42) creates an object of type MyClass on the stack. As soon as SomeFunc() returns the MyClass object is destroyed, as all objects in that stackframe are popped off.

So now, outside of SomeFunc the caller has a reference to an invalid object, hence the crash, or in general the outcome is undefined.


As a general rule, you never return references to local objects.

Advertisement
Yes, I haven't experience with C++ as well. :) But initially I added destructor to class definition:

~MyClass()
{
print("My class destructed\n");
}

And if I had seen this message in output, I shouldn't have posted this report.
And about compilation errors. As I can see, it's not related to references though.

I get this message:
Assertion failed: tempVariables.GetLength() == 0, file ..\..\source\as_compiler.cpp, line 614

for following (synthetic) code:
string SomeFunc(){    return null;}void main(){}
All assert failures in the library indicates some bug. I'll take a look at this at the earliest possible moment.

However, I can tell you already that the script language doesn't support returning references yet. This is because it requires careful checking of what the reference actually points to, so that it can be guaranteed that the reference is valid after the function returns.

AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

Quote: Original post by marvi
And about compilation errors. As I can see, it's not related to references though.

I get this message:
Assertion failed: tempVariables.GetLength() == 0, file ..\..\source\as_compiler.cpp, line 614

for following (synthetic) code:
string SomeFunc(){    return null;}void main(){}


To fix this bug, apply the following changes to as_compiler.cpp near line 1147:

void asCCompiler::PrepareArgument(asCDataType *paramType, asSExprContext *ctx, asCScriptNode *node, bool isFunction, int refType, asCArray<int> *reservedVars){	...   	// Need to protect arguments by reference	if( isFunction && dt.IsReference() )	{		...	}	else	{		if( dt.IsPrimitive() )		{			...		}		else		{			IsVariableInitialized(&ctx->type, node);			// Implicitly convert primitives to the parameter type			ImplicitConversion(ctx, dt, node, false, true, reservedVars);Add this code --->>			// Was the conversion successful?			if( !ctx->type.dataType.IsEqualExceptRef(dt) )			{				asCString str;				str.Format(TXT_CANT_IMPLICITLY_CONVERT_s_TO_s, ctx->type.dataType.Format().AddressOf(), dt.Format().AddressOf());				Error(str.AddressOf(), node);								ctx->type.Set(dt);			}<<---			...		}	}	// Don't put any pointer on the stack yet	if( param.IsReference() || param.IsObject() )	{		// &inout parameter may leave the reference on the stack already		if( refType != 3 )		{			ctx->bc.Pop(PTR_SIZE);			ctx->bc.InstrSHORT(BC_VAR, ctx->type.stackOffset);		}		ProcessDeferredParams(ctx);	}}


Hopefully I'll be able to check in this fix soon.

I still need to investigate the first bug you reported. I'll let you know as soon as I have the solution for it.

AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

Advertisement
I've checked in fixes for both problems now.

AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

This topic is closed to new replies.

Advertisement