Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

question on allocation on assignment, TYPE(t) vs CLASS(t)

16 views
Skip to first unread message

Nasser M. Abbasi

unread,
Mar 29, 2011, 7:28:12 PM3/29/11
to
Fortran experts:

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

steve

unread,
Mar 29, 2011, 7:41:22 PM3/29/11
to Nasser M. Abbasi
On Mar 29, 4:28 pm, "Nasser M. Abbasi" <n...@12000.org> wrote:

> -------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

Tobias Burnus

unread,
Mar 30, 2011, 3:43:21 AM3/30/11
to
On 03/30/2011 01:28 AM, Nasser M. Abbasi wrote:
> My question is: Why does one have to do an explicit
> ALLOCATE when using CLASS, and not when using TYPE?

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

reubendb

unread,
Mar 30, 2011, 1:48:41 PM3/30/11
to
On Mar 29, 7:28 pm, "Nasser M. Abbasi" <n...@12000.org> wrote:
> 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.

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.

0 new messages