Hi there,
I recently updated to the latest AngelScript version from … like 2014 or something. Had to rewrite some parts of my script bindings, especially the asBehaviour vs. opStuff functions.
Small side note: why? This is not an improvement, and it seriously complicated my math library. More on that at the end.
But first: the crash: AngelScript code looks like this
AssignSomeColor( TColor( GetColor()) * pow( 0.1f, GetTimeDiff()));
Severely reduced snippet. Involved operators are these:
explicit constexpr TColor::TColor( const TAlphaColor& f) noexcept { ... }
inline constexpr TColor operator * (const TColor& f, float scale) noexcept
{ return TColor{ ... };
}
mEngine->RegisterObjectBehaviour( "TColor", asBEHAVE_CONSTRUCT, "void f( const TAlphaColor& in)", asFUNCTIONPR( ScriptHelper::ConstructColor, (const TAlphaColor &, TColor *), void), asCALL_CDECL_OBJLAST);
mEngine->RegisterObjectMethod( "TColor", "TColor opMul( float)", asFUNCTIONPR( operator *, (const TColor&, float), TColor), asCALL_CDECL_OBJFIRST);
So it looks like a standard set of constructor and operator overload. But it crashes. Something in the above line leads AngelScript to pass the TColor argument of operator * by value instead of by reference. It crashes inside the operator * with the first Argument being the bit value of a float disguised as a pointer/reference. With some ugly inspection magic I can actually see the three floats being passed by value. The method registration cited above is a class method, so it should pass the first arg by reference.
Am I doing something wrong? I have a whole bunch of these operator invocations all over the script functions. And they work everywhere else. TColor * float, float * TColor, TColor / float, all fine. The only difference I can spot is that in this line I'm creating a temporary TColor object.
And concerning the opStuff method of registering operator overloads: this forces the C++ operators to take their arguments as const ref. And this leads to less-than-ideal code generation in CLang and Visual Studio. In simple cases the Compiler emits the same code, in some more complex cases though this leads to severe performance regressions. I understand this is the way now, but I still wanted you to know.
Thanks in advance for any hint or comment. Oh wow, it must be 10 years and I still have that signature. I'm not even an indie anymore.