[Release b] <t4m_bug_dtor_const> Wed Jun 23 15:42:59 WEST 2004 In the current release of tendra4minix (a), after fixing <t4m_bug_applyfunctempl>, the program dtor_const.C produces this error, "dtor_const.C", line 6: Error: [ISO 14.7.1]: In instantiation of template 'Hola < int >::~Hola' (at line 6). [ISO 12.6.2]: In special member function 'Hola < int >::~Hola ()'. [ISO 8.5]: In initialization of 'Hola < int >::i'. [ISO 8.5]: 'const' objects should be initialized. This is the error ERR_dcl_init_const generated in init_default [construct.c] and reported in constr_error [construct.c]. It is reported only for polymorphic (= having virtual functions) template classes. Function make_destr_prelude [construct.c], called from ctor_none [construct.c] (which is always called from the parser) at hashid_destr_tag, creates a dummy initializer for destructors of polymorphic classes; this initializer is used for resetting virtual tables just before destruction takes place. The error happens when copy_exp [copy.c] is instantiating this initializer, which has kind DEFAULT_PRELUDE; copy_exp calls copy_ctor [construct.c], as it should do for any initializer, and then copy_ctor immediately calls make_constr [construct.c], since there are no arguments for this initializer. make_constr calls init_empty_mem [construct.c] for each data member of the class, and finally init_empty_mem calls init_default [construct.c] to create the default initializer. It is in init_default when the error is generated. The error does not happen during class template analysis because the initializer expression built by make_destr_prelude is added to the destructor body after make_constr has been called (see ctor_none [construct.c]). And it does not happen with non-template classes because they are not copied (= instantiated), and make_constr is never called again for them. Assuming that DEFAULT_PRELUDE is only used to reset virtual tables, as the comment at make_destr_prelude says, we can fix this problem just adding the condition 'n == DEFAULT_PRELUDE' to the conditional /* Everything else is alright in these cases */ if ( n == DEFAULT_COPY || n == DEFAULT_DESTR || n == DEFAULT_DELETE ) { return ( NULL_exp ) ; } in function init_default [construct.c], obtaining /* Everything else is alright in these cases */ if ( n == DEFAULT_COPY || n == DEFAULT_DESTR || n == DEFAULT_DELETE || n == DEFAULT_PRELUDE ) { return ( NULL_exp ) ; } Note: the resetting of virtual tables for data members is supposed to be done inside their own destructors, thus in theory we could even avoid calling init_default when n == DEFAULT_PRELUDE, but in this way the change is minimal. Question: How come members of template classes don't get reinitialized at the beginning of destructors due to the instantiation of the DEFAULT_PRELUDE initializer? Members of built-in types and enumerations should be initialized explicitly inside special functions. For members of class types, init_default calls find_constr [construct.c] to find the appropriate constructor, but find_constr returns NULL_id when the kind of the special function requested is DEFAULT_PRELUDE (see dtor_const_c.C for an example).