Advertisement

Operator problems

Started by October 10, 2005 02:11 AM
3 comments, last by Dentoid 19 years, 1 month ago
Hey Long time since I posted anything here, and unfortunately now when I do it's because I'm having problems. I've got this C++ class "csVector3" that is a standard vector (in the geometrical sense) class. It's got three members:

      /// The X component of the vector
      float x;
      /// The Y component of the vector
      float y;
      /// The Z component of the vector
      float z;
Also, it has a bunch of operators, with the most important beeing:

  /// Add two vectors.
  inline friend csVector3 operator+(const csVector3& v1, const csVector3& v2)
    { return csVector3(v1.x+v2.x, v1.y+v2.y, v1.z+v2.z); }

  /// Subtract two vectors.
  inline friend csVector3 operator-(const csVector3& v1, const csVector3& v2)
    { return csVector3(v1.x-v2.x, v1.y-v2.y, v1.z-v2.z); }

  /// Multiply a vector and a scalar.
  inline friend csVector3 operator* (const csVector3& v, float f)
    { return csVector3(v.x*f, v.y*f, v.z*f); }

  /// Multiply a vector and a scalar.
  inline friend csVector3 operator* (float f, const csVector3& v)
    { return csVector3(v.x*f, v.y*f, v.z*f); }

  /// Divide a vector by a scalar int.
  inline friend csVector3 operator/ (const csVector3& v, int f)
    { return v / (float)f; }

  /// Multiply this vector by a scalar.
  inline csVector3& operator*= (float f)
    { x *= f; y *= f; z *= f; return *this; }

  /// Divide this vector by a scalar.
  inline csVector3& operator/= (float f)
    { f = 1.0f / f; x *= f; y *= f; z *= f; return *this; }

  /// Add another vector to this vector.
  inline csVector3& operator+= (const csVector3& v)
  {
    x += v.x;
    y += v.y;
    z += v.z;

    return *this;
  }

  /// Subtract another vector from this vector.
  inline csVector3& operator-= (const csVector3& v)
  {
    x -= v.x;
    y -= v.y;
    z -= v.z;
    return *this;
  }
It's also got a couple of constructors, but no destructor or assignments. I register this class to AngelScript like this:

    engine->RegisterObjectType ("Vector3", sizeof (csVector3), asOBJ_CLASS_C);
    engine->RegisterObjectProperty ("Vector3", "float x", offsetof(csVector3, x));
    engine->RegisterObjectProperty ("Vector3", "float y", offsetof(csVector3, y));
    engine->RegisterObjectProperty ("Vector3", "float z", offsetof(csVector3, z));
    engine->RegisterObjectBehaviour ("Vector3", asBEHAVE_CONSTRUCT, "void f()", asFUNCTIONPR(ConstructVector3, (csVector3*), void), asCALL_CDECL_OBJLAST);

    engine->RegisterObjectBehaviour ("Vector3", asBEHAVE_CONSTRUCT, "void f(float, float, float)", asFUNCTIONPR(ConstructVector3, (float, float, float, csVector3*), void), asCALL_CDECL_OBJLAST);

    engine->RegisterObjectMethod ("Vector3", "float Length()", asMETHODPR(csVector3, Norm, (void) const, float), asCALL_THISCALL);

    engine->RegisterObjectMethod ("Vector3", "void Normalize()", asMETHOD(csVector3, Normalize), asCALL_THISCALL);

    engine->RegisterGlobalBehaviour (asBEHAVE_ADD, "Vector3 f(Vector3 ∈, Vector3 ∈)", asFUNCTIONPR(operator+, (const csVector3&, const csVector3&), csVector3), asCALL_CDECL);

    engine->RegisterGlobalBehaviour (asBEHAVE_SUBTRACT, "Vector3 f(Vector3 ∈, Vector3 ∈)", asFUNCTIONPR(operator-, (const csVector3&, const csVector3&), csVector3), asCALL_CDECL);

    engine->RegisterGlobalBehaviour (asBEHAVE_MULTIPLY, "Vector3 f(Vector3 ∈, float)", asFUNCTIONPR(operator*, (const csVector3&, float), csVector3), asCALL_CDECL);

    engine->RegisterGlobalBehaviour (asBEHAVE_MULTIPLY, "Vector3 f(float, Vector3 ∈)", asFUNCTIONPR(operator*, (float, const csVector3&), csVector3), asCALL_CDECL);

    engine->RegisterGlobalBehaviour (asBEHAVE_DIVIDE, "Vector3 f(Vector3 ∈, float)", asFUNCTIONPR(operator/, (const csVector3&, float), csVector3), asCALL_CDECL);

    engine->RegisterObjectBehaviour ("Vector3", asBEHAVE_ADD_ASSIGN, "Vector3 &f(Vector3 ∈)", asMETHODPR(csVector3, operator+=, (const csVector3&), csVector3&), asCALL_THISCALL);

    engine->RegisterObjectBehaviour ("Vector3", asBEHAVE_SUB_ASSIGN, "Vector3 &f(Vector3 ∈)", asMETHODPR(csVector3, operator+=, (const csVector3&), csVector3&), asCALL_THISCALL);

    engine->RegisterObjectBehaviour ("Vector3", asBEHAVE_MUL_ASSIGN, "Vector3 &f(float)", asMETHODPR(csVector3, operator*=, (float), csVector3&), asCALL_THISCALL);

    engine->RegisterObjectBehaviour ("Vector3", asBEHAVE_DIV_ASSIGN, "Vector3 &f(float)", asMETHODPR(csVector3, operator/=, (float), csVector3&), asCALL_THISCALL);
Okay, so now to my problems. When using this class, I sometimes get crashes in the operators. I've got a line like this:

if(something) {
...
Vector3 newPos1 = meshOrigin + sideVector*0.1f + frontVector*stepLength;
...
} else {
...
}
Here all variables except stepLength are Vector3s, while stepLength is a float. It crashes in the first addition. (v1 in operator+ becomes a broken reference, null). If I for example remove the "sideVector*0.1f" it works. Also if I move the calculation outside the "if" it works. It also works if I split it up to:

   Vector3 newPos2 = meshOrigin;
   newPos2 += sideVector*0.1f;
   newPos2 += frontVector*stepLength;
So basically if you shuffle it around a bit or so you might get lucky. Maybe I've done something wrong somewhere, but I've checked my configuration a lot and it seems correct to me. So, I think there might be something wrong in how operators work in some cases, but I haven't been able to identify the exact circumstances. I realize this may be a bit thin info, but it's all I can give right now I think. Any ideas whatsoever? Thanks /Anders EDIT: Changed the subject, since I accidentally left it as "Untitled". [Edited by - Dentoid on October 10, 2005 9:22:22 AM]
Holy redundant comments batman!

Your C++ operators return references. You tell angelscript they return by value.
Advertisement
Quote: Original post by Deyja
Holy redundant comments batman!

Your C++ operators return references. You tell angelscript they return by value.


Unless I'm overlooking something silly, only the assignment operators return references, the others return by value.
Indeed, I cannot see anything wrong in your registration.

From your description it sounds like a problem with the AngelScript compiler. I guess it is either reusing a temporary variable that it shouldn't, or it is releasing a temporary too early. By splitting the expression into several statements, you should be able to avoid this problem.

I will look into this, as soon as possible. I'll stop working on 2.5.0 for a while and fix all the reported bugs for 2.4.1.



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

Yeah, splitting it works so I'm not totally locked. Thanks for looking into it!

This topic is closed to new replies.

Advertisement