Dear all, I faced with a possible serious bug: polymorphic functions (necessary to define polymorphic operators in OOP programs) generate memory leaks making OOP program not feasible.
I opened a bug report (80477) here https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80477 I report the details also below. My best regards. Issue summary In the attached example "polymorphic_operators_memory_leaks.f90" I show the possible bug in less than 100 lines. Essentially, the derived type "a_type_t" defines the operators "=" and "+" in a polymorphic way (in order to allow "a_type_t" to be extended while all other "agents" using "a_type_t" do not need to be changed, OOP). The assignment operator does not create memory leaks because it is subroutine that does not allocate temporary. On the contrary, the operator "+" is a function that allocates a temporary: this temporary generates the memory leaks because it is not correctly destroyed after its usage. I checked the above conclusion with "valgrind" and it confirms that the "+" operator (function) generates the leaks. Note that the same code compiled and run with Intel Fortran (17.0.2) does not generates memory leaks and it works as expected. Moreover, is the "+" operator/function is modified disallowing polymorphic (namely changing "class(a_type_t), allocatable :: res" with "type(a_type_t) :: res" the leaks disappear, thus I could conclude that the leaks are generated only for polymorphic function results. A word of advice: the test is designed to point out the memory leaks occurrences, running it your RAM will be quickly consumed! Please, be rapid to quickly kill it before your OS start swapping on HD. To test it with valgrind I added a little "ui": it can be executed without arguments, thus its loop will be very long (and your RAM totally consumed) or you can pass one integer argument and the loop will do the iterations you provided, e.g. "a.out 1" will execute 1 iteration loop. This is written into the code comments. Please, consider that if this is really a bug, all serious OOP programs are indeed impossible to be done. Thank you very much for your help. Stefano Zaghi Ph.D. Aerospace Engineer Research Scientist, Dept. of Computational Hydrodynamics at CNR-INSEAN p: +39 0650299260 | m: +39 3497730036 | e: stefano.za...@gmail.com Member of Fortran-FOSS-Programmers Codes Showcase OFF Open source Finite volumes Fluid dynamics code Lib_VTK_IO Fortran library to write and read data conforming the VTK standard FLAP Fortran command Line Arguments Parser for poor men BeFoR64 Base64 encoding/decoding library for FoRtran poor men FiNeR Fortran INI ParseR and generator for FoRtran poor men IR_Precision Fortran (standard 2003) module to develop portable codes FoBis.py Fortran Building System for poor men PreForM.py Preprocessor for Fortran poor men MaTiSSe.py Markdown To Impressive Scientific Slides
module a_type_m implicit none integer, parameter :: LENGTH = 100 type :: a_type_t real :: x(LENGTH) contains ! operators generic :: assignment(=) => assign_a_type generic :: operator(+) => add_a_type procedure, pass(lhs) :: assign_a_type procedure, pass(lhs) :: add_a_type endtype a_type_t contains subroutine assign_a_type(lhs, rhs) ! Operator `=`. class(a_type_t), intent(inout) :: lhs class(a_type_t), intent(in) :: rhs lhs%x = rhs%x endsubroutine assign_a_type function add_a_type(lhs, rhs) result( res ) ! Operator `+`. class(a_type_t), intent(in) :: lhs class(a_type_t), intent(in) :: rhs class(a_type_t), allocatable :: res allocate (a_type_t :: res) res%x = lhs%x + rhs%x endfunction add_a_type endmodule a_type_m program polymorphic_operators_memory_leaks ! pass one argument to limit the loop iterations, e.g.: ! a.out 4 # the loop will be limited to 4 iterations ! useful for testing with valgrind; ! a.out # the loop will run for LENGHT**3 iterations use a_type_m implicit none character(99) :: switch type(a_type_t) :: a type(a_type_t) :: b integer :: N integer :: i a%x = [(i, i=1, LENGTH)] b = a i = command_argument_count() if (i == 1) then call get_command_argument(1,switch) read(switch, *) N else N = LENGTH**3 endif do i=1, N b = a + b ! here the `+` operator generates memory leaks if (mod(i,10**5) == 0) print*, i enddo endprogram polymorphic_operators_memory_leaks