Consider the following example:
Type B
Declare Constructor (ByVal i As Integer)
Value As Integer
End Type
Constructor B (ByVal i As Integer)
This.Value = i
End Constructor
Type D Extends B
Declare Constructor
End Type
Constructor D
Base(0)
End Constructor
When the compiler reaches End Type of type D, it issues an error 188: Missing UDT.constructor(byref as const UDT) implementation (base UDT without default constructor requires manual initialization), found 'End' in 'End Type'
The error is superfluous because the default constructor of type B is never called. Could it be removed?
Tested with Version 1.08.1 (2021-07-08), built for linux-x86_64 (64bit)
Default-constructor and copy-constructor:
If an UDT is missing any of the two, the compiler has to generate them automatically if a base or field has any constructors, in order to ensure the base/field are always getting constructed properly. However, if the base/field only has a non-default constructor, then the auto-generation isn't possible and the coder must help out (if any non default-constructors are declared, the compiler does not provide a default-constructor and the user is forced to declare one if necessary).
See in changelog.txt:
Before version 0.24.0, a code like yours was allowed, but the copy-construction of a derived instance could be bugged (for a string field in the base for example: shallow copy instead of deep copy because string field badly constructed).
See in the Programmer's Guide "2. Rules of good manners (for constructors, copy-constructors, copy-assignment operators, and destructors)":
https://www.freebasic.net/wiki/wikka.php?wakka=ProPgCtorsAssignDtors2#ProPgCtorsAssignDtors22
See also "#578 Non-default base type ctor not autocalled, yet no error":
https://sourceforge.net/p/fbc/bugs/578/
Simplest workaround:
The non-default base constructor modified to allow optional parameters:
Other workarounds:
Constructor B (),Constructor D (Byref As Const D).Last edit: fxm (freebasic.net) 2021-11-21
fxm, thanks for your extensive explanation. I found it also works to declare a default constructor for type B without defining it, as long as it is not actually called, in which case it is required anyway.
P.S. I guess this ticket can be closed now.