Advertisement

RegisterObjectMethod() crash registering a const reference?

Started by September 03, 2024 11:54 PM
3 comments, last by Servant of the Lord 2 months ago

I have a class like this:

struct EnemyTypeDetails {
//...blah...
};

class Enemy {
public:
Enemy(const EnemyTypeDetails &type) : typeRef(type) { }

const EnemyTypeDetails &typeRef; //What I want, but can't register
const EnemyTypeDetails *typePtr;
}


This crashes: within the ‘RegisterObjectProperty()’ function.
asCheck(engine->RegisterObjectProperty("Enemy", "const EnemyTypeDetails &type", asOFFSET(Enemy, typeRef)));

It crashes with the following error from my debugger:

The inferior stopped because it triggered an exception.
Stopped in thread 0 by: Exception at 0x7ff7c2ae805e, code: 0xc0000005: read access violation at: 0x186b0, flags=0x0

Am I registering the reference wrong?

This does not crash: (exposing a pointer member instead of a reference member)
asCheck(engine->RegisterObjectProperty("Enemy", "const EnemyTypeDetails &type", asOFFSET(Enemy, typePtr)));

Note: I'm using Angelscript 2.36.0

I've never seen this error before. To me both the * and the & are stored in the same way, so it should work.

But I don't think I have any case like this in the regression test suite, so it might be some nuance that requires some change to support member references.

I'll investigate.

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 found out that the asOFFSET macro doesn't support taking the offset of members that are references. It simply doesn't return the correct offset.

The same happens for the standard offsetof(s, m) defined in stddef.h, and also for the Microsoft specific __builtin_offsetof(s, m).

As far as I can tell, the reason for it failing is that when trying to take the address of typeRef with &Enemy->typeRef you're actually getting the address that the reference is referring to rather than the address where it is stored in the type.

I haven't found a way rewrite the asOFFSET macro to work for this case, but you can manually calculate the offset and register the property if you want. For example with:

// Calculate the offset of Enemy::typeRef relatively to an adjacent member
engine->RegisterObjectProperty("Enemy", "const EnemyTypeDetails &type", asOFFSET(Enemy, typePtr) - sizeof(void*)); 

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

Ah, that makes sense. I forget that additional nitpicky nature of references potentially not existing, and just tend to think of them as pointers. Some googling for a general solution reveals that the standard forbids us from getting the actual reference's address, because hypothetically it might not exist. Seems like a limitation that the C++ standard should relax for member variables, though!

Thank you for the awesome language.

This topic is closed to new replies.

Advertisement