Advertisement

Constructors behaving strangely

Started by October 01, 2024 09:36 AM
4 comments, last by WitchLord 1 day, 19 hours ago

The following code will cause a null exception in the else block in the Foo constructor.

class Bar {
	int m_value;
	Bar(int value) { m_value = value; }
}

class Foo {
	Bar m_bar;
	Foo(bool b) {
		if (b) m_bar = Bar(1);
		else m_bar = Bar(2);
	}
}

Foo g_foo(false);

The following produces similar results:

class Bar {
	int m_value;
	Bar(int value) { m_value = value; }
}

class Foobase {
	Bar m_a;
	Bar m_b;
	Foobase(bool b) {
		m_a = Bar(1);
		if (b) return;
		m_b = Bar(2);
	}
}

class Foo : Foobase {
	Foo() {
		super(true);
		m_b = Bar(3);
	}
}

Foo g_foo;

I assume this is related to this change:

- Added engine property asEP_MEMBER_INIT_MODE to allow backwards compatiblity for how class members are initialized
- A class member can now be explicitly initialized in the class constructor, overriding the initialization defined in the declaration

I really like this change, but I feel like the behavior described above is probably a bug?

Not a bug, just not fully implemented yet. 😊

I was just about to start working on the support for initializing members within conditions. As it is now, it will definitely fail, since the initialization only happens in the first case, and in the else it will attempt a normal assignment to an uninitialized member.

I'll let you know when this has been implemented.

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've implemented the support for initializing members in if-else statements now. Both conditions must initialize the same members, else an error will be reported.

https://sourceforge.net/p/angelscript/code/2966/

There is still more work to do, e.g.

- prohibit initialization of members in loops
- give error if member is not initialized in all code paths, e.g if there is initialization after a conditional return (your second example)
- prohibit initialization of members in switch statements (I don't think I will make the effort to implement the logic to make sure all code paths initialize the same members)
- make sure members that don't have default constructors and no explicit initialization give a proper error
- make sure member access before explicit initialization is properly handled (I haven't decided exactly how this should be handled, but it should not result in runtime error)

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

Thanks! Looking forward to this feature.

As a side note, since this might break compatibility a ton - is it possible for this engine option (and perhaps other engine options) to be part of the script module instead of the script engine instead? I don't know enough about the internals for this to be sure if it makes sense at the module level, but that way I can let script writers decide whether they want to use this feature or not.

Depending on the engine property it can be changed before each compilation. So the ones that are only affecting how the compiler behaves can definitely be per module.

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