I have an object (it happens to be a reference object, but I don't think that matters). I register the following behavior so that the object can implicitly cast to a double.
engine->RegisterObjectBehaviour("type", asBEHAVE_IMPLICIT_VALUE_CASE, "double f() const", asMETHOD(type, operator double), asCALL_THISCALL);
The implicit cast works properly in an assignment to a local variable, but it does not work in an assignment to a global variable. "Can't implicitly convert from 'type&' to 'double&'."
double g_Value;
void main()
{
type x;
double Value;
Value = x; //<-- Works fine
g_Value = x; //<-- Compile Error
}
The problem seems to be that the left side of the assignment operator for a local variable is not a reference, but for a global variable it is a reference.
In the CompileVariableAccess function:
as_compiler.cpp(7717):
if( ctx->type.dataType.IsPrimitive() )
{
// Load the address of the variable into the register
ctx->bc.InstrPTR(asBC_LDG, prop->GetAddressOfValue());
ctx->type.dataType.MakeReference(true);
}
Then, in the ImplicitConvObjectToPrimitive function, the destination type (left-hand side) is compared to the return type of implicit cast function.
as_compiler.cpp(5476)
// Find the best matching cast operator
int funcId = 0;
if( row )
{
asCDataType target(to);
// Priority goes from left to right in the matrix
for( unsigned int attempt = 0; attempt < 10 && funcId == 0; attempt++ )
{
target.SetTokenType(row[attempt]);
for( unsigned int n = 0; n < funcs.GetLength(); n++ )
{
asCScriptFunction *descr = builder->GetFunctionDescription(funcs[n]);
if( descr->returnType.IsEqualExceptConst(target) )
{
funcId = funcs[n];
break;
}
}
}
}
Since the comparison is performed with "IsEqualExceptConst", the comparison fails ("double&" from the global variable on the left and "double" from the return of my function on the right)
I'm not certain what the most appropriate fix is, but my first impression is that changing the comparison to use "IsEqualExceptRefAndConst" may be correct.