I spend 3 days to build gcc 4.6, and now I have gfortran 4.6 on my linux.
$ gfortran -v
Using built-in specs.
COLLECT_GCC=gfortran
COLLECT_LTO_WRAPPER=/usr/local/libexec/gcc/i686-pc-linux-gnu/4.6.0/lto-wrapper
Target: i686-pc-linux-gnu
Configured with: ./configure
Thread model: posix
gcc version 4.6.0 (GCC)
My question is the following: I have defined a
TYPE ::foo_t
which contains an array, which I do not know
the size of yet, so I declare it as ALLOCATBLE.
When the object is created, in the constructor, the
caller will pass an array which I want to save inside
the object as the initial data.
I find that in the constructor, I need to use the ALLOCATE
statement to allocate space ONLY when I use CLASS(foo_t).
But when I use TYPE(foo_t), then I do not need to do an
ALLOCATE. It seems allocation happens automatically.
The reason I found this, is that I wanted to implement
object%method(....) call, and not method(object,....)
But object%method(...) will only work when one uses CLASS
and not TYPE. see below:
http://www.mail-archive.com/gcc-...@gcc.gnu.org/msg232349.html
Now, I show 2 examples. In the first one, I use
the CALL object%method(...) (requires CLASS), and in the
second example, using CALL method(object,....) (can use TYPE)
My question is: Why does one have to do an explicit
ALLOCATE when using CLASS, and not when using TYPE?
I really do not understand the different between TYPE and
CLASS yet. But I justed wanted to use CALL object%method()
and that is why I had to change TYPE to CLASS.
example 1: using CALL method(object,....), NO ALLOCATE is
needed (allocation on assignment ok)
------------- main2.f90
program main2
use foo
implicit none
TYPE(foo_t) :: o
DOUBLE PRECISION , ALLOCATABLE :: u(:)
u=[1,2,3,4]
CALL make(o,u);
end program main2
---------------------------------
---- foo.f90 ------------
module foo
implicit none
type :: foo_t
private
DOUBLE PRECISION , ALLOCATABLE :: u(:)
end type foo_t
contains
subroutine make(this,u)
implicit none
TYPE(foo_t) :: this ! notice type not class here
DOUBLE PRECISION, intent(in) :: u(:)
this%u = u ! notice, allocation on assignment OK
end subroutine make
end module foo
-------------------------------
EXAMPLE 2 using CALL object%method(....), must use CLASS,
and must also use ALLOCATE
---- main2.foo-----------------
program main2
use foo
implicit none
TYPE(foo_t) :: o
DOUBLE PRECISION , ALLOCATABLE :: u(:)
u=[1,2,3,4]
CALL o%make(u)
end program main2
----------------------------
------------ foo.f90--------------
module foo
implicit none
type :: foo_t
private
DOUBLE PRECISION , ALLOCATABLE :: u(:)
contains
PROCEDURE :: make ! or procedure, pass, same effect
end type foo_t
contains
subroutine make(this,u)
implicit none
CLASS(foo_t) :: this
DOUBLE PRECISION, intent(in) :: u(:) ! must be CLASS
allocate(this%u(size(u))) ! Must allocate now, else crash
this%u = u
end subroutine make
end module foo
----------------------------
-------build.sh--------
gfortran -std=f2003 -Wextra -Wall -pedantic -funroll-loops
-ftree-vectorize -march=native -Wsurprising -Wconversion -c foo.f90
gfortran -std=f2003 -Wextra -Wall -pedantic -funroll-loops
-ftree-vectorize -march=native -Wsurprising -Wconversion main2.f90 foo.o
--------------------------
In example 2, if I do not allocate, then program will segment fault.
Thank you,
--Nasser
> -------build.sh--------
> gfortran -std=f2003 -Wextra -Wall -pedantic -funroll-loops
> -ftree-vectorize -march=native -Wsurprising -Wconversion -c foo.f90
>
> gfortran -std=f2003 -Wextra -Wall -pedantic -funroll-loops
> -ftree-vectorize -march=native -Wsurprising -Wconversion main2.f90 foo.o
> --------------------------
Can't help you with your guestion. But, I will suggest that
you may not want to use -pedantic. It may not do what you
think it does.
--
steve
In the general case: Fortran 2003 does not allow a polymorphic variable
on the left-hand side of an assignment - there are too many issues
involved to get this properly working. Fortran 2008 essentially keeps
that restriction, but allows assignment to an allocatable polymorphic
variable, where the (re)allocation happens automatically, if needed.
The latter is not yet implemented in gfortran - but you will get an
error message at compile time.
However, that's not what you have:
> type :: foo_t
> DOUBLE PRECISION , ALLOCATABLE :: u(:)
> end type foo_t
> subroutine make(this,u)
> CLASS(foo_t) :: this
> DOUBLE PRECISION, intent(in) :: u(:) ! must be CLASS
> this%u = u
Here, "this%u" is not polymorphic but a normal allocatable variable.
Thus, Fortran 2003's (re)allocate on assignment should work.
As it doesn't with gfortran 4.6/4.7, I have filled a problem report (PR)
at http://gcc.gnu.org/bugzilla/show_bug.cgi?id=48351
Tobias
I think there are two separate issues here.
The first one is related to the passed-object as dummy argument to
type-bound procedure. The standard require this to be polymorphic,
that means using of CLASS, if the type is entensible. I think the
reasoning is so that an extension of the type can still use this
parent's type-bound procedure since the passed-object would be type
compatible. Most derived type is 'extensible' unless if it has
SEQUENCE of BIND(C) attribute, so basically as rule of thumb is that
you have to use CLASS to declare the passed-object dummy argument.
The second issue is related to the automatic (re-)allocation. This is
a new feature of Fortran 2003, and yes your example is right in that
you actually do not need to explicitly allocate, even if you use "this
%u=u" and "this" is passed-object with CLASS keyword. The "u" in "this
%u" is just primitive variable array variable. So this seems to be a
bug in gfortran, as Tobias pointed out.