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

Copying derived type

849 views
Skip to first unread message

Gib Bogle

unread,
Jun 14, 2012, 9:09:05 PM6/14/12
to
I have something like this:

type bar_type
integer :: i, j, k
real :: x, y, z
real :: a(100), b(100), c(100)
end type

type fu_type
integer :: m, n
real :: p, q
type(bar_type), pointer :: bar
end type

type(fu_type), allocatable :: fu(:)

...
allocate(fu(max_nlist))
do k = 1,max_nlist
nullify(fu(k)%bar)
enddo

Later some of the fu(:)%bar are allocated. Later still I want to copy
fu(i) to fu(j) for some i and j. The way I'm doing it now is member by
member, which is error-prone because it's possible to forget to modify
the copy subroutine when the member list is changed (I just spent an
hour tracking down such a mistake, after adding a new member.)

Is there a better way to copy one such derived type variable to another?

Richard Maine

unread,
Jun 14, 2012, 9:39:12 PM6/14/12
to
I Guess I don't understand the problem. Hmm. Or then, maybe I do. It
depends on what you mean by "copy". Just plain old

fu(j) = fu(i)

should do an intrinsic assignment (aka "copy") just fine. I'm guessing
that

1. The "copy" that you want is not the same one that intrinsic
assignment does.

and further

2. That's because your component bar would be more naturally expressed
as allocatable instead of a pointer.

In that case, the natural solution would be to make the component
allocatable instead of pointer. Then intrinsic assignment will do what I
suspect you expect. Of course, that does require a compiler that
supports allocatable components.

Another possible approach would be to make a defined assignment for your
derived type. Unfortunately, that can be awfully tricky if you want to
make a pointer component act like one would expect allocatables to. You
are very likely to end up with memory leaks and other problems that way.
It is so much cleaner to just use allocatables.

If this doesn't happen to be your problem, then you'll have to explain
it better, because, as noted above, fu(j)=fu(i) *DOES* copy fu(i) to
fu(j). But bar being a pointer, it copies the pointer - not the target
of the pointer.

--
Richard Maine
email: last name at domain . net
domain: summer-triangle

glen herrmannsfeldt

unread,
Jun 14, 2012, 9:49:03 PM6/14/12
to
Gib Bogle <g.b...@too.auckland.much.ac.spam.nz> wrote:
> I have something like this:

(snip)

> type(fu_type), allocatable :: fu(:)

> allocate(fu(max_nlist))
> do k = 1,max_nlist
> nullify(fu(k)%bar)
> enddo

> Later some of the fu(:)%bar are allocated. Later still I want to copy
> fu(i) to fu(j) for some i and j. The way I'm doing it now is member by
> member, which is error-prone because it's possible to forget to modify
> the copy subroutine when the member list is changed (I just spent an
> hour tracking down such a mistake, after adding a new member.)

> Is there a better way to copy one such derived type variable to another?

As far as I know, you can assign whole structures. That is:

fu(i)=fu(j)

Your program, with the addition of that statement and removal of ...
compiles with gfortran.

You can't, though, do something like fu(i)=0 in Fortran.
(Zero all structure members.)

PL/I allows structure expressions, such as fu(i)=0, fu(i)=2*fu(j),
or fu(i)=fu(j)+fu(k) but Fortran still doesn't.

-- glen

glen herrmannsfeldt

unread,
Jun 14, 2012, 10:33:40 PM6/14/12
to
Richard Maine <nos...@see.signature> wrote:

(snip)
>> type fu_type
>> integer :: m, n
>> real :: p, q
>> type(bar_type), pointer :: bar
>> end type

(snip)
>> Is there a better way to copy one such derived type variable to another?

> I Guess I don't understand the problem. Hmm. Or then, maybe
> I do. It depends on what you mean by "copy". Just plain old

> fu(j) = fu(i)

(snip)
> If this doesn't happen to be your problem, then you'll have to explain
> it better, because, as noted above, fu(j)=fu(i) *DOES* copy fu(i) to
> fu(j). But bar being a pointer, it copies the pointer - not the target
> of the pointer.

In that case, the easiest to me would be to do the assignment, which
will copy all the non-pointers and also the pointer, then allocate
a new bar_type, copy to that one, and assign its pointer.

That, at least, allows for new non-pointers to copy without
extra work.

-- glen

Gib Bogle

unread,
Jun 14, 2012, 11:05:16 PM6/14/12
to
On 15/06/2012 1:39 p.m., Richard Maine wrote:
...
>> Is there a better way to copy one such derived type variable to another?
>
> I Guess I don't understand the problem. Hmm. Or then, maybe I do. It
> depends on what you mean by "copy". Just plain old
>
> fu(j) = fu(i)
>
> should do an intrinsic assignment (aka "copy") just fine. I'm guessing
> that
>
> 1. The "copy" that you want is not the same one that intrinsic
> assignment does.
>
> and further
>
> 2. That's because your component bar would be more naturally expressed
> as allocatable instead of a pointer.
>
> In that case, the natural solution would be to make the component
> allocatable instead of pointer. Then intrinsic assignment will do what I
> suspect you expect. Of course, that does require a compiler that
> supports allocatable components.
>
> Another possible approach would be to make a defined assignment for your
> derived type. Unfortunately, that can be awfully tricky if you want to
> make a pointer component act like one would expect allocatables to. You
> are very likely to end up with memory leaks and other problems that way.
> It is so much cleaner to just use allocatables.
>
> If this doesn't happen to be your problem, then you'll have to explain
> it better, because, as noted above, fu(j)=fu(i) *DOES* copy fu(i) to
> fu(j). But bar being a pointer, it copies the pointer - not the target
> of the pointer.
>

This is the point where my understanding is fuzzy. I have been assuming
that I need to copy the target. fu(j) may be reused later, at which
time if %bar is not needed it is deallocated.

A quick test of making %bar allocatable instead of pointer generated a
lot of compiler errors, most because I check associated(fu(j)%bar) to
determine what sort of thing fu(j) is. I could replace all these
"associated" with "allocated", and take care of the other compiler
errors. But the solution Glen suggests seems to require fewer changes -
I can comment out all the non-pointer component-to-component
assignments, and use instead fu(i) = fu(j), while leaving the copying of
the pointer target. There is only, and will only ever be, one pointer
component.

Nasser M. Abbasi

unread,
Jun 14, 2012, 11:05:23 PM6/14/12
to
On 6/14/2012 8:39 PM, Richard Maine wrote:
> Gib Bogle<g.b...@too.auckland.much.ac.spam.nz> wrote:

>
> Another possible approach would be to make a defined assignment for your
> derived type. Unfortunately, that can be awfully tricky if you want to
> make a pointer component act like one would expect allocatables to. You
> are very likely to end up with memory leaks and other problems that way.
> It is so much cleaner to just use allocatables.
>

That is the problem with adding all these new features to Fortran.

It has become a dynamic language, with all the problem that
brings to it. Now one has to think of deep copy vs. shallow
copy.

Fortran used to be a simple language where A=B means copy what is
B to A.

End of story.

Adding Pointers to Fortran makes no sense. Fortran is not c++
and it should not have been modified to become c++.

--Nasser




Richard Maine

unread,
Jun 14, 2012, 11:58:21 PM6/14/12
to
Nasser M. Abbasi <n...@12000.org> wrote:

> Adding Pointers to Fortran makes no sense. Fortran is not c++
> and it should not have been modified to become c++.

Well, it certainly would have made the job of answering Fortran
questions a lot easier if it had just stopped at f77.... because there
would be a lot fewer people using Fortran at all. For example, I would
not have been using it. I am *VERY* confident that a lot of other people
would also have eventually abandoned the language (or not learned it in
the first place).

Right around when f90 came out, I had already made the decision that f77
was no longer suitable for my use, in spite of the fact that I had been
using Fortran as my primary language for over 2 decades even then and
had become pretty proficient in it. Working around its numerous
shortcommings was just becoming too much of a pain. I hadn't decided
what I was going to be programming in, but I had decided that it was no
longer going to be F77. After a fair amount of researching alternatives,
I settled on f90.

By the way, pointers in Forran were not modelled at all after those in
C++. Heck, they weren't even modeled after those in C.

But I'm not sure why I bother to reply, as I'm equally sure that nothng
I have to say will change your opinions on the matter.

--
Richard Maine | Good judgment comes from experience;
email: last name at domain . net | experience comes from bad judgment.
domain: summertriangle | -- Mark Twain

Richard Maine

unread,
Jun 15, 2012, 12:03:37 AM6/15/12
to
Gib Bogle <g.b...@too.auckland.much.ac.spam.nz> wrote:

> This is the point where my understanding is fuzzy. I have been assuming
> that I need to copy the target. fu(j) may be reused later, at which
> time if %bar is not needed it is deallocated.

Then yes, that's very much a case of it naturally "wanting" to be
allocatable instead of pointer. If the target should only ever have one
pointer pointing to it, then it isn't really being used as a pointer; it
is being used as a hack for allocatables having been severely incomplete
in earier versions of the standard.

> A quick test of making %bar allocatable instead of pointer generated a
> lot of compiler errors, most because I check associated(fu(j)%bar) to
> determine what sort of thing fu(j) is. I could replace all these
> "associated" with "allocated", and take care of the other compiler
> errors. But the solution Glen suggests seems to require fewer changes -
> I can comment out all the non-pointer component-to-component
> assignments, and use instead fu(i) = fu(j), while leaving the copying of
> the pointer target. There is only, and will only ever be, one pointer
> component.

Just be aware that using pointers this way is very error-prone, and the
errors can be tricky to track down. Heck, pointers are error-prone in
general, but there aren't good alternatives for some uses of pointer.

James Van Buskirk

unread,
Jun 15, 2012, 12:19:21 AM6/15/12
to
"Nasser M. Abbasi" <n...@12000.org> wrote in message
news:jre8pk$krv$1...@speranza.aioe.org...

> Adding Pointers to Fortran makes no sense. Fortran is not c++
> and it should not have been modified to become c++.

Building data structures can be a lot easier with pointers. If I
were to create AVL trees in Fortran, for example, I definitely
would use pointers.

The problem with forgetting to modify the copy subroutine when
the member list is modified can be guarded against. Consider
the following code:

C:\gfortran\clf\def_assign>type types.f90
module fu_mod
implicit none
type bar_type
integer :: i, j, k
real :: x, y, z
real :: a(100), b(100), c(100)
end type bar_type

type fu_type
integer :: m, n
real :: p, q
type(bar_type), pointer :: bar
end type fu_type

contains
subroutine fu_assign(x,y)
type(fu_type), intent(out) :: x
type(fu_type), intent(in) :: y
type(bar_type), pointer :: bar
! Start pointer section
if(associated(x%bar)) then
deallocate(x%bar)
end if
if(associated(y%bar)) then
allocate(bar)
bar = y%bar
else
nullify(bar)
end if
! End pointer section
x = fu_type( &
m = y%m, &
n = y%n, &
p = y%p, &
q = y%q, &
bar = bar)
end subroutine fu_assign
end module fu_mod

module fu_mod_2
use fu_mod

interface assignment(=)
module procedure fu_assign
end interface assignment(=)

end module fu_mod_2

This compiles fine with gfortran. However, if I add an extra
member to type(fu_type):

type fu_type
integer :: m, n
real :: p, q
complex s
type(bar_type), pointer :: bar
end type fu_type

gfortran detects my error:

C:\gfortran\clf\def_assign>gfortran -c types.f90
types.f90:32.13:

x = fu_type( &
1
Error: No initializer for component 's' given in the structure constructor
at (1
)!
types.f90:42.7:

use fu_mod
1
Fatal Error: Can't open module file 'fu_mod.mod' for reading at (1): No such
fil
e or directory

But if you want to use pointers like this you should probably
have a finalizer for type(fu_type).

--
write(*,*) transfer((/17.392111325966148d0,6.5794487871554595D-85, &
6.0134700243160014d-154/),(/'x'/)); end


Gib Bogle

unread,
Jun 15, 2012, 2:01:45 AM6/15/12
to
On 15/06/2012 4:03 p.m., Richard Maine wrote:
> Gib Bogle<g.b...@too.auckland.much.ac.spam.nz> wrote:
>
>> This is the point where my understanding is fuzzy. I have been assuming
>> that I need to copy the target. fu(j) may be reused later, at which
>> time if %bar is not needed it is deallocated.
>
> Then yes, that's very much a case of it naturally "wanting" to be
> allocatable instead of pointer. If the target should only ever have one
> pointer pointing to it, then it isn't really being used as a pointer; it
> is being used as a hack for allocatables having been severely incomplete
> in earier versions of the standard.

In the interests of better programming practice, I've implemented the
change from pointer to allocatable. I notice that I cannot do this:

logical :: u
type(bar_type) :: b
b = fu(i)%bar
u = allocated(b)

I must either have
type(bar_type),allocatable :: b
or instead use
u = allocated(fu(i)%bar)

Ron Shepard

unread,
Jun 15, 2012, 3:11:14 AM6/15/12
to
In article <jrej4e$a93$1...@speranza.aioe.org>,
Gib Bogle <g.b...@too.auckland.much.ac.spam.nz> wrote:

> In the interests of better programming practice, I've implemented the
> change from pointer to allocatable.

I think most compilers now support allocatable scalars, so that is
reasonably portable. However, you might still find outdated
compilers in use that do not do that. Specifically, fu(i)%bar is a
scalar, not an array. It has arrays in it, but it is a scalar.

> I notice that I cannot do this:
>
> logical :: u
> type(bar_type) :: b
> b = fu(i)%bar

Provided the rhs has been allocated, this assignment is correct. It
makes a copy in the variable b. If the rhs is not allocated, then
this assignment is not legal.

> u = allocated(b)

Well of course you can't do this because b is not allocatable. What
are you trying to determine here? This just doesn't make sense,
does it?

>
> I must either have
> type(bar_type),allocatable :: b

Okay, this raises another issue. Recent compilers now support a new
feature called "allocate on assignment". I forget if this is f2003
or f2008, but it is one of these recent standards. If this is
supported, then you can assign

b = fu(i)%bar

without first knowing the status of the rhs. The scalar b then ends
up with the same allocation status as the rhs. I don't use this
yet, so I'm not fluent with this syntax, but I'm pretty sure this is
correct.

> or instead use
> u = allocated(fu(i)%bar)

Yes, this would always work, and it does the obvious thing. What I
don't understand is what you were trying to do above. That is not
obvious.

There are good reasons to include pointers in the language. There
are things like network data structures (linked lists, trees, and so
on) that are much simpler and clearer to implement in terms of
pointers. But fortran also has allocatable arrays (and more
recently allocatable scalars) which in many ways are more powerful,
robust, and clearer and simpler to use than pointers. Lesser
languages sometimes only have pointers and not allocatables. It is
a good thing that the language has both types of entities. It is a
shame that f90 had a fairly complete implementation of pointers, but
only a limited implementation of allocatables. That caused many
programmers to start programming projects with the wrong approach.
It is also surprising that this occurred, considering the
decade-long delay of ratification that occurred in the 80's, which
one might have thought would have resulted in a complete, solid, and
robust specification of all the new features. But, that is the way
it was done. In any case, compilers now support both types of
entities very well.

$.02 -Ron Shepard

Wolfgang Kilian

unread,
Jun 15, 2012, 3:13:29 AM6/15/12
to
On 06/15/2012 05:05 AM, Nasser M. Abbasi wrote:
> On 6/14/2012 8:39 PM, Richard Maine wrote:
>> Gib Bogle<g.b...@too.auckland.much.ac.spam.nz> wrote:
>
>>
>> Another possible approach would be to make a defined assignment for your
>> derived type. Unfortunately, that can be awfully tricky if you want to
>> make a pointer component act like one would expect allocatables to. You
>> are very likely to end up with memory leaks and other problems that way.
>> It is so much cleaner to just use allocatables.
>>
>
> That is the problem with adding all these new features to Fortran.

20+ years ago is not precisely 'new' in terms of software development?

> It has become a dynamic language, with all the problem that
> brings to it. Now one has to think of deep copy vs. shallow
> copy.

You have to think in those terms if your data/algorithms require it. It
was done all the time in F66 or F77, just all dynamic memory management
had to be emulated, using large fixed-sized arrays as workspace, and
array indices etc. as pointers. Doable, but awkward.

> Fortran used to be a simple language where A=B means copy what is
> B to A.
>
> End of story.

The idea of 'allocatable' is to maintain this behavior. You run into
troubles here only IF you are using pointers. Which sometimes is well
justified, however.

> Adding Pointers to Fortran makes no sense. Fortran is not c++
> and it should not have been modified to become c++.

I'd guess that part of the idea behind Fortran90 (which unfortunately
took until F2003 to develop consistently) was to gain sufficient
flexibility while avoiding some of the known and common pitfalls of
C/C++. Some people do like the solution.

-- Wolfgang

--
E-mail: firstnameini...@domain.de
Domain: yahoo

Nasser M. Abbasi

unread,
Jun 15, 2012, 3:27:03 AM6/15/12
to
On 6/15/2012 2:13 AM, Wolfgang Kilian wrote:

>
>> Adding Pointers to Fortran makes no sense. Fortran is not c++
>> and it should not have been modified to become c++.
>
> I'd guess that part of the idea behind Fortran90 (which unfortunately
> took until F2003 to develop consistently) was to gain sufficient
> flexibility while avoiding some of the known and common pitfalls of
> C/C++. Some people do like the solution.
>
> -- Wolfgang
>

Any many more do not. That is why c++ is now used more than Fortran
for scientific number crunching software. Just search
any site which lists scientific libraries, and you'll see
more c++ than Fortran. Here is one for finite elements

http://en.wikipedia.org/wiki/List_of_finite_element_software_packages

The reason is simple. Fortran threw the ball on its main
strengths, and tried to chase the current fashion by
adding OO and pointers to look like c++. Fortran has
managed to become more complex to use than c++. An amazing
achievement for any language to achieve.

When a language tries to emulate another language, people
will then move to the real one instead of using the emulation.

Fortran should have added modules, records, but stayed at the
level of ADT and improvements made to make the language
more robust for numerical work. But the main effort should
have been put into adding more numerical standard libraries and
functions, and not muck and ruin what was the classical language for
number crunching to something that has no identity any more.

--Nasser

Ian Harvey

unread,
Jun 15, 2012, 3:40:33 AM6/15/12
to
On 2012-06-15 5:11 PM, Ron Shepard wrote:
...
> Okay, this raises another issue. Recent compilers now support a new
> feature called "allocate on assignment". I forget if this is f2003
> or f2008, but it is one of these recent standards. If this is
> supported, then you can assign
>
> b = fu(i)%bar
>
> without first knowing the status of the rhs. The scalar b then ends
> up with the same allocation status as the rhs. I don't use this
> yet, so I'm not fluent with this syntax, but I'm pretty sure this is
> correct.

F2003.

BUT there is still the requirement for the rhs to be allocated (if the
right hand side happened to be an allocatable thing) - assignment
doesn't copy the allocatation status - it copies the value of the
expression on the right hand side. Getting the value of that expression
involves referencing the variable on the right hand side and unallocated
things may not be referenced.

On the otherhand...

CALL MOVE_ALLOC(fu(i)%bar, b)

transfers the allocation (including the allocation status) from
fu(i)%bar to b. But this is a move, not a copy - so fu(i)%bar will not
be allocated after this statement.

Ian Harvey

unread,
Jun 15, 2012, 4:20:48 AM6/15/12
to
Pointers have been around since F90, but the other aspect - object
oriented programming, was only added in F2003. F2003 compilers have
only just become available, far too late to have influenced the choice
of language behind most (if not all) of those packages.

So, if anything, your list of packages suggest that the reason other
languages have been chosen was *because* Fortran lacked features found
in those other languages.

Others have pointed out that Fortran's pointers aren't modelled on C's
(and hence C++'s). Guess what... its object oriented implementation
isn't modelled on C++'s either. The changes made to the language hardly
make it look like C++.

If you think that Fortran is as complicated as C++, then you clearly
don't know C++. I happily use both languages, daily. I have more years
of C++ experience than Fortran experience, but by far Fortran is the
language I've ended up being more familiar with.

Library development and language development are mostly orthogonal.

Features such as OO (and C binding) have made it easier for people to
write libraries, or at least adapt existing libraries so that Fortran
can use them.

I'd be keen to see language development go further down the path of
making it easier for library writers, but the changes and features that
I feel would be required would even further add to to language complexity.

In the meantime, if someone wants to write a better numerical library or
whatever, using the language as it stands F90-sans-pointers, what's
stopping them?

Wolfgang Kilian

unread,
Jun 15, 2012, 4:26:16 AM6/15/12
to
On 06/15/2012 09:27 AM, Nasser M. Abbasi wrote:
> On 6/15/2012 2:13 AM, Wolfgang Kilian wrote:
>
>>
>>> Adding Pointers to Fortran makes no sense. Fortran is not c++
>>> and it should not have been modified to become c++.
>>
>> I'd guess that part of the idea behind Fortran90 (which unfortunately
>> took until F2003 to develop consistently) was to gain sufficient
>> flexibility while avoiding some of the known and common pitfalls of
>> C/C++. Some people do like the solution.
>>
>> -- Wolfgang
>>
>
> Any many more do not. That is why c++ is now used more than Fortran
> for scientific number crunching software.

In can speak only for my field in physics: No, C++ is used here more
than Fortran simply because the major players (CERN, in particular)
decided to move from F77 to C++ without considering F90 an alternative.

Reasons as they were communicated:
- Fortran 90 (Fortran8x at that time) would have been preferred but
was not finished in time. And once finished, there was no
free/open-source compiler for a long time.
- If young scientists learn C++, they are well prepared for business
outside of fundamental science. Because C++ would eventually replace
COBOL (not Fortran). [Actually, Java took over.]

These reasons were completely valid at that time. I would also have
switched to C++, but stayed with Fortran only because somebody
introduced me to the F90 concepts and the NAG compiler, for which we
happened to have a license.

[The strange thing is that the actual new C++ code that I see (in my
field) often looks very much like F77 with different syntax.]

Jos Bergervoet

unread,
Jun 15, 2012, 4:42:38 AM6/15/12
to
On 6/15/2012 9:27 AM, Nasser M. Abbasi wrote:
..
> Fortran should have added modules, records, but stayed at the
> level of ADT and improvements made to make the language
> more robust for numerical work.

The most important addition are the allocatables
and allocatable components. They were not (widely)
available before about 2000. This may have caused
many people to use C++. There you had to write a
few constructor, destructor, and access routines,
which then gave you all benefits you could *not*
get from fortran without allocatable components.

The benefits I mean are of course:
. Automatic use of dynamic memory
. Guaranteed free of memory-leaks
. No dangling references possible.

> But the main effort should
> have been put into adding more numerical standard libraries and

But if we stick to the language itself, then it
really was the lack of dynamic memory that gave us
the most restrictions in f77.

Of course array syntax and derived types are a good
addition as well, just like the overloading of the
assignment and other operators.

And pointers? Pointer arrays are the wrong solution
for the most severe f77 problem. And they were
introduced instead of the correct solution! (Which,
admittedly, was added later..)

--
Jos

dpb

unread,
Jun 15, 2012, 6:22:11 AM6/15/12
to
On 6/15/2012 2:27 AM, Nasser M. Abbasi wrote:
> On 6/15/2012 2:13 AM, Wolfgang Kilian wrote:
>
>>
>>> Adding Pointers to Fortran makes no sense. Fortran is not c++
>>> and it should not have been modified to become c++.
>>
>> I'd guess that part of the idea behind Fortran90 (which unfortunately
>> took until F2003 to develop consistently) was to gain sufficient
>> flexibility while avoiding some of the known and common pitfalls of
>> C/C++. Some people do like the solution.
>>
>> -- Wolfgang
>>
>
> Any many more do not. That is why c++ is now used more than Fortran
> for scientific number crunching software....

Simply nonsense...

C++ is larger because Fortran took too long to get to where it is and C
was already larger general use well before then...

--

Ron Shepard

unread,
Jun 15, 2012, 12:52:14 PM6/15/12
to
In article <jrf2ch$dmv$1...@speranza.aioe.org>, dpb <no...@non.net>
wrote:
This has been stated several times in this thread, and I agree. C
was not standardized until 1989, and there were major problems with
K&R C before that time for scientific/numerical programming. It was
the slow progress of fortran in the decade of the 80's that gave C
time to mature and flourish.

IMO, here is what *should* have occurred in the decade of the 80's.
Almost immediately after f77 was approved, there should have been a
minor revision to the standard that basically included all of the
mil-std features (standard bit operators, implicit none, etc.); this
alone would have solved many problems with portability. Then what
was eventually f90 should have been adopted a few years later in the
1984 to 1985 timeframe. The problems with adopting the standard was
not that the features had not been set, it was that some of the
vendors were intentionally trying to delay approval of the ANSI
standard in order to milk competitive advantages with their existing
f77 compilers. Some vendors had worked very hard, and done a very
good job, of optimizing f77 code, and they believed that the
introduction of high-level constructs such as array syntax would
obviate that effort and make those same optimizations available to
their competitors with essentially no effort. In retrospect, this
belief was at least partly unfounded. So they drug their feet, year
after year after year. Eventually, the international committee ISO
forced the hand of the ANSI committee by approving the f90 standard
without ANSI. That had never happened before, and it shows how
broken the ANSI committee was at the time. So all of this feet
dragging gave other languages, mostly C, time to take root and
establish themselves. But even in the early 90's, the vast majority
of scientific programming was still done with fortran, not with C or
C++, and the other languages du jour such as java had not yet been
invented. But that decade of obstruction is what let these lesser
languages become popular.

A related issue is the availability of a free compiler. F77 had the
f2c converter and later the g77 compiler. But the typical fortran
compiler was still something that was developed in-house by a
hardware vendor. It was designed specifically to take advantage of
whatever hardware features were available at that time (VLIW
instruction sets, RISC, parallel threads, NUMA, special floating
point units, etc.). C compilers in contrast were used more like
assemblers, implementing more low-level nonportable code than
high-level portable code. Most computers at the time had a free C
compiler, and including the gcc compiler, sometimes there were
actually several C compilers available on a computer. In contrast,
fortran compilers were expensive and only one would be available on
any given computer. It would take another decade after f90, until
the early 21st century, before gfortran would give fortran users a
similar programming environment.

This is also why so many programming courses in college were based
on C rather than fortran in the 80's and 90's, and the number of
trained programmers is yet another reason for the popularity of C
compared to fortran.

So in hindsight, imagine if the delays by the ANSI committee had
been avoided, and imagine if gfortran (or something similar, such as
a new f2c) had been available in the mid 1980's rather than the mid
2000's. Given the choice between gfortran and K&R C, most
scientific, engineering, and numerical programming would almost
certainly have stayed with fortran. Fortran would have remained the
main programming language taught in colleges, and things would be
very very different now.

$.02 -Ron Shepard

dpb

unread,
Jun 15, 2012, 2:51:18 PM6/15/12
to
On 6/15/2012 11:52 AM, Ron Shepard wrote:
> In article<jrf2ch$dmv$1...@speranza.aioe.org>, dpb<no...@non.net>
> wrote:
>> On 6/15/2012 2:27 AM, Nasser M. Abbasi wrote:
>>> On 6/15/2012 2:13 AM, Wolfgang Kilian wrote:
>>>
>>>>
>>>>> Adding Pointers to Fortran makes no sense. Fortran is not c++
>>>>> and it should not have been modified to become c++.
>>>>
>>>> I'd guess that part of the idea behind Fortran90 (which unfortunately
>>>> took until F2003 to develop consistently) was to gain sufficient
>>>> flexibility while avoiding some of the known and common pitfalls of
>>>> C/C++. Some people do like the solution.
....
>>> Any many more do not. That is why c++ is now used more than Fortran
>>> for scientific number crunching software....
>>
>> Simply nonsense...
>>
>> C++ is larger because Fortran took too long to get to where it is and C
>> was already larger general use well before then...
>
> This has been stated several times in this thread, and I agree. C
> was not standardized until 1989, and there were major problems with
> K&R C before that time for scientific/numerical programming. It was
> the slow progress of fortran in the decade of the 80's that gave C
> time to mature and flourish.
...[narrative of a revised Fortran history elided for brevity]...

> A related issue is the availability of a free compiler. F77 had the
> f2c converter and later the g77 compiler. But the typical fortran
> compiler was still something that was developed in-house by a
> hardware vendor. ...
> ... Most computers at the time had a free C
> compiler, and including the gcc compiler, sometimes there were
> actually several C compilers available on a computer. In contrast,
> fortran compilers were expensive and only one would be available on
> any given computer. It would take another decade after f90, until
> the early 21st century, before gfortran would give fortran users a
> similar programming environment.
>
> This is also why so many programming courses in college were based
> on C rather than fortran in the 80's and 90's, and the number of
> trained programmers is yet another reason for the popularity of C
> compared to fortran.
>
> So in hindsight, imagine if the delays by the ANSI committee had
> been avoided, and imagine if gfortran (or something similar, such as
> a new f2c) had been available in the mid 1980's rather than the mid
> 2000's. Given the choice between gfortran and K&R C, most
> scientific, engineering, and numerical programming would almost
> certainly have stayed with fortran. Fortran would have remained the
> main programming language taught in colleges, and things would be
> very very different now.
>
> $.02 -Ron Shepard

For the most part, agree fully.

One thing I observed back in those 80s and the use of C almost
exclusively in university courses was that many of the prof's were proud
of the arcane syntax of C sorta' like the early days before the PC
revolution when there was the mystique of the computer behind closed
doors only accessible to the elite. At least my reading of many while
touring the country doing on-campus recruiting for my employer of the
time...trying to find talent for support and development of the large
nuclear (and other as well altho the nuke codes tended to be the most
challenging) design codes was a prime objective on my rounds.

--

glen herrmannsfeldt

unread,
Jun 15, 2012, 5:15:00 PM6/15/12
to
Ron Shepard <ron-s...@nospam.comcast.net> wrote:

(snip)
>> C++ is larger because Fortran took too long to get to where
>> it is and C was already larger general use well before then...

> This has been stated several times in this thread, and I agree. C
> was not standardized until 1989, and there were major problems with
> K&R C before that time for scientific/numerical programming. It was
> the slow progress of fortran in the decade of the 80's that gave C
> time to mature and flourish.

I suppose, but even so K&R wasn't that bad.

> IMO, here is what *should* have occurred in the decade of the 80's.
> Almost immediately after f77 was approved, there should have been a
> minor revision to the standard that basically included all of the
> mil-std features (standard bit operators, implicit none, etc.); this
> alone would have solved many problems with portability. Then what
> was eventually f90 should have been adopted a few years later in the
> 1984 to 1985 timeframe.

Personally, I was rooting for 1988, to keep the 66, 77, 88
trend going. (I don't know about the 99, 00 though.)

> The problems with adopting the standard was
> not that the features had not been set, it was that some of the
> vendors were intentionally trying to delay approval of the ANSI
> standard in order to milk competitive advantages with their existing
> f77 compilers. Some vendors had worked very hard, and done a very
> good job, of optimizing f77 code, and they believed that the
> introduction of high-level constructs such as array syntax would
> obviate that effort and make those same optimizations available to
> their competitors with essentially no effort. In retrospect, this
> belief was at least partly unfounded. So they drug their feet, year
> after year after year.

I was mostly doing Fortran programming in the 1977-1986 time frame,
but had pretty much no connection to what the vendors were doing,
other than what appeared in the manuals that they published.

(snip)
> So all of this feet
> dragging gave other languages, mostly C, time to take root and
> establish themselves. But even in the early 90's, the vast majority
> of scientific programming was still done with fortran, not with C or
> C++, and the other languages du jour such as java had not yet been
> invented. But that decade of obstruction is what let these lesser
> languages become popular.

I suppose, but it might also have been changes is what "scientific
computing" was doing around that time. Among others, the expansion
of computational biology. As the DNA database grew exponentially
(I believe it still is) the need for programs to process the data
also grew. But unlike much of scientific computing, computational
biology does a lot of fixed point work with small integers,
and a lot of character work. Also, computational biology uses
more pure math (things like graph theory) than computational
physics or chemistry (the more traditional scientific computing).

More (theoretical) computer science people became involved,
and not so many from the "numerical analysis" community.

Also around that time frame was big growth in work with symbolic
math, leading to systems like SMP, Maple, and Mathematica.
Again, reduces need for floating point number crunching and
more character comparisons.

It could have been two separate scientific communities, and might
have been if a new Fortran came earlier, but eventually people
talk to others, and ideas spread and mix.

> A related issue is the availability of a free compiler. F77 had the
> f2c converter and later the g77 compiler. But the typical fortran
> compiler was still something that was developed in-house by a
> hardware vendor.

Well, this was also the transition from the large computing
center to individual workstations. A large computing center
might have had enough people to license an expensive Fortran
compiler, but maybe not the individual worker.

> It was designed specifically to take advantage of
> whatever hardware features were available at that time (VLIW
> instruction sets, RISC, parallel threads, NUMA, special floating
> point units, etc.). C compilers in contrast were used more like
> assemblers, implementing more low-level nonportable code than
> high-level portable code. Most computers at the time had a free C
> compiler,

I don't know about "most", but for many years the unix sysgen
process required a C compiler, so the OS had to come with one.
That wasn't true for other OS, though, but unix was expanding
into the scientific community.

On the other hand, for DEC systems that I remember at the time,


> and including the gcc compiler, sometimes there were
> actually several C compilers available on a computer. In contrast,
> fortran compilers were expensive and only one would be available on
> any given computer. It would take another decade after f90, until
> the early 21st century, before gfortran would give fortran users a
> similar programming environment.

Sounds about right to me.

> This is also why so many programming courses in college were based
> on C rather than fortran in the 80's and 90's, and the number of
> trained programmers is yet another reason for the popularity of C
> compared to fortran.

Well, if taught by the numerical analysis community they
might have been in Fortran, but the CS community liked Pascal,
and then C.

It seems to me that there has been a merging of the more tranditional
CS (theoretical computer science) and CE (computer engineering,
including hardware) into CSE (computer science and engineering).
Another trend which has an effect on how things are taught.

> So in hindsight, imagine if the delays by the ANSI committee had
> been avoided, and imagine if gfortran (or something similar, such as
> a new f2c) had been available in the mid 1980's rather than the mid
> 2000's. Given the choice between gfortran and K&R C, most
> scientific, engineering, and numerical programming would almost
> certainly have stayed with fortran. Fortran would have remained the
> main programming language taught in colleges, and things would be
> very very different now.

Maybe for the numerical programming. Engineering has been moving
to higher level interpreted languages, such as Matlab, as computers
became faster. It seems to me that the scientific community was
changing enough that I am not convinced it would have stuck so
completely with Fortran.

-- glen

Gib Bogle

unread,
Jun 15, 2012, 6:01:05 PM6/15/12
to
On 15/06/2012 4:03 p.m., Richard Maine wrote:
> Gib Bogle<g.b...@too.auckland.much.ac.spam.nz> wrote:
>
>> This is the point where my understanding is fuzzy. I have been assuming
>> that I need to copy the target. fu(j) may be reused later, at which
>> time if %bar is not needed it is deallocated.
>
> Then yes, that's very much a case of it naturally "wanting" to be
> allocatable instead of pointer. If the target should only ever have one
> pointer pointing to it, then it isn't really being used as a pointer; it
> is being used as a hack for allocatables having been severely incomplete
> in earier versions of the standard.
...

I spoke too soon. Although the modifications I made enabled the program
to compile and execute, it did not do what was intended. The trouble is
that I'm using pointers in a couple of different ways, and I didn't
think through the implications of the changes I was making. I often
pass a pointer to %bar to a subroutine that modifies its contents. I
thoughtlessly changed
p => fu(i)%bar
to
p = fu(i)%bar
and used p as the argument to the subroutine, but overlooked the need to
copy the result back into fu(i)%bar. Let's draw a veil over that ...

If it wasn't for the different usages in my code, simply changing the
declaration of %bar from pointer to allocatable would be sufficient.
(I convinced myself of this with the test code at the end of this post.)
Unfortunately I did not adopt a completely consistent coding style in
my program, which is now rather large.

Sometimes I have
p => fu(i)%bar
if (associated(p)) ...
and sometimes
if (associated(fu(i)%bar)) ...

The former is still OK if %bar is made allocatable, but the latter is
not. Similarly if asub is a subroutine that takes a pointer argument,

call asub(p)
is OK, but
call asub(fu(i)%bar)
is not.

These points are all obvious to me now, but being very rusty on this
stuff and having a terrible memory it took me a while to catch on. When
I realized that many more changes were required to do it properly I went
back to my original code using %bar as a pointer, which at least has the
virtue of working.

module test

type bar_type
real :: a(100)
end type

type fu_type
integer :: m
! type(bar_type), pointer :: bar
type(bar_type), allocatable :: bar
end type

type(fu_type), target :: fu(1000)

contains

subroutine asub(k)
integer :: k
type(bar_type), pointer :: p
p => fu(k)%bar
if (associated(p)) then
write(*,*) 'allocated bar in element: ',k
call bsub(p,0.0)
else
write(*,*) 'unallocated bar in element: ',k
endif
end subroutine

subroutine bsub(p,b)
type(bar_type), pointer :: p
real :: b
p%a = b
end subroutine

end module

program main
use test
integer :: k
do k = 1,10
allocate(fu(k)%bar)
enddo
call asub(5)
call asub(20)
end

0 new messages