Advertisement

Various unexpected behaviors of AngelScript 2.31.0

Started by March 22, 2016 04:07 PM
5 comments, last by WitchLord 8 years, 6 months ago

Ternary conditional operator applied to two null handles:


class foo {}
void main() {
	foo@ bar = true ? null : null;
}
Outcome: Compile error: Can't implicitly convert from '<null handle>' to 'foo@&'.
Expected outcome: Compiles, bar is initialized to null.
The expression has little use outside of temporary code / debugging, but it's reasonable to expect it to compile.
Auto initialized to null:

void main() {
	auto foo = null;
}
Outcome: Null pointer access in asCDataType::CanBeInstantiated, crash.
Expected outcome: Compile error or foo is of null handle type.

Again, there is typically no reason to do this, and it's not necessary that it compile, but ideally the engine would not crash when given incorrect code.

Return reference to void:


void& f() {
	return f();
}
Outcome: Compiles.
Expected outcome: Compile error: Data type cannot be reference to void.
Not very dangerous, because the only thing such a function can return is the result of another function that return void&, but this shouldn't be allowed to compile nonetheless.
Take reference to void:

void f(void &in, void &in) {}
void g() {}
void main() {
	f(g(), g());
}
Outcome: Assertion failure in asCCompiler::ConvertToVariable.
Expected outcome: Compile error: Data type cannot be reference to void.
A more malicious version of the previous issue.
Void value used as argument of function that takes no arguments.

void f() {}
void main() {
	f(f());
}
Outcome: Compiles, calls f twice.
Expected outcome: Compile error: Function f does not take arguments.

This is a bit of a special case, because I notice it's akin to C function definitions where functions that take no parameters are declared to take void, but wherever this kind of syntax is encountered, it appears to me that it's almost certain it's in error. Perhaps minimally a warning would be in place in this case.

All, except the last are valid bugs and I'll look into them, and have them fixed a.s.a.p.

The last one is as you suspect a special case, and while it may look odd, it is specifically designed to work so that this type of expression can be used in code where you don't know at the time of writing the actual type of the argument given to the function. Consider for example macros, templates, or mixins, where you write the code once and then reuse it in different situations.

I also have a case in the console sample that takes advantage of this. Here I register various overloads of a special function called _grab that is used to catch the value of the expression written on the console input line and print it on the screen. When the expression doesn't have any value (i.e. void) then the overload _grab() is used. The statement written to the console input is then compiled and executed by the application like this:


void ExecString(asIScriptEngine *engine, string &arg)
{
  string script;
 
  // Wrap the expression in with a call to _grab, which allow us to print the resulting value
  script = "_grab(" + arg + ")";
 
  int r = ExecuteString(engine, script.c_str(), engine->GetModule("console"));
  if( r < 0 )
    cout << "Invalid script statement. " << endl;
  else if( r == asEXECUTION_EXCEPTION )
    cout << "A script exception was raised." << endl;
}

If this is causing a problem for you I could add an engine property to allow you to turn off this behaviour in your application.

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

Thanks for explaining; sounds very reasonable. No, I don't need it disabled, given that it's intended to be permitted syntax, possesses well-defined behavior, and has legitimate use cases. That's sufficient to rename it from a bug to a feature in my book.

I've fixed all the bugs reported here in revision 2308.

Thanks,

Andreas

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

Looks like the "auto foo = null;" crash may still occur when declared in the global scope.

Thanks for letting me know. I'll look into 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

Fixed in revision 2322.

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