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

Smart pointer

57 views
Skip to first unread message

egio

unread,
Dec 6, 2010, 12:15:00 PM12/6/10
to
I was wondering about the possibility to havesmart pointers in the
next FORTRAN standard. As far as I know they will be present in the
next C++.
More then the pointers, I think, that the allocatables may be extended
in order to have more than one allocation. Of course I don't know how
big this effort may be and all the subtleties involved.

I'm thinking at a syntax like:

type(xxx), nultiallocatable :: a, b
allocate(a) ! Allocated
call add_alloc(a, b) ! now a and b are alias
deallocate(a) ! a is deallocated
but b is still valid and allocated
deallocate(b) ! now the memory is
really deallocated

It may be useful for example if an object is something

type(yyy)
type(xxx), multiallocatable :: b
endtype

and I don't have to worry if b is deallocated someware else.
Thanks,

Richard Maine

unread,
Dec 6, 2010, 12:48:48 PM12/6/10
to
egio <edmondo.g...@gmail.com> wrote:

> I was wondering about the possibility to havesmart pointers in the
> next FORTRAN standard. As far as I know they will be present in the
> next C++.

I'm afraid I don't know what you mean by a "smart pointer".

> More then the pointers, I think, that the allocatables may be extended
> in order to have more than one allocation. Of course I don't know how
> big this effort may be and all the subtleties involved.
>
> I'm thinking at a syntax like:
>
> type(xxx), nultiallocatable :: a, b
> allocate(a) ! Allocated
> call add_alloc(a, b) ! now a and b are alias
> deallocate(a) ! a is deallocated
> but b is still valid and allocated
> deallocate(b) ! now the memory is
> really deallocated

It would help to give a definition instead of an example. Trying to
define things by example is notoriously tricky - more so when the
examples are not of actual constructs, so we have to guess what the
example is doing too.

Note that syntax is the *LAST* step in defining a feature for inclusion
on the language.

But if (and that is a very big "if") I am following the example
correctly, it sounds like you are just talking about what I think
normally falls under the description of garbage collection. Everything
else sounds like normal pointer use, with your add_alloc just being a
normal pointer assignment and your deallocate really being a nullify.
The memory is not deallocated until after it is no longer accessible by
any pointer. If that's what you mean, mandate garbage collection and you
have it. Whather you could get such a mandate to pass is another
question, and one I won't try to weigh in on.

That's enough for me on this for now. It is just too speculative as to
what the OP is actually asking for and this could all be completely
unrelated to what he means.

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

egio

unread,
Dec 6, 2010, 3:31:42 PM12/6/10
to
On 6 Dic, 18:48, nos...@see.signature (Richard Maine) wrote:

Well, you are right, I was thinking to a sort of garbage collection
by counting the number of pointers referencing to a single memory
location. I thought that it would have been easier to add this feature
to allocatable variables.
I have seen that some c++ libraries (like for example the QT)
implements a sort of smart pointer, and it would have been interesting
to have it on Fortran. Of course it was a speculation.

But I thanks you for the answer, I hope that if in the future I need a
more concrete help I can count on you.

Thanks in advance

Edmondo Giovannozzi

glen herrmannsfeldt

unread,
Dec 6, 2010, 3:45:21 PM12/6/10
to
egio <edmondo.g...@gmail.com> wrote:

(snip)

> More then the pointers, I think, that the allocatables may be extended
> in order to have more than one allocation. Of course I don't know how
> big this effort may be and all the subtleties involved.

(snip of example that I don't understand)

The PL/I version of ALLOCATABLE, called CONTROLLED, stacks in
the case of multiple ALLOCATE statements before FREE.
That can be especially useful in the case of RECURSIVE routines.
One can keep pointers to previous instances of such variables,
or just wait until they unstack.

I don't know the subtleties, either. As for syntax, I would say
that another attribute (I suggest STACKABLE) would be enough.
It is the implementation details that complicate this feature.

I believe that the ability to pass internal procedures as actual
arguments was finally added in Fortran 2008. Some of the
complication of doing that has to do with the environment that
goes along with the call. For PL/I the environment of the call
includes the appropriate instances of AUTOMATIC variables.
(As they were when the CALL was made, even if they change since.)
I am not so sure about CONTROLLED, but it would seem that
the nesting level might also be part of the environment.

-- glen

Richard Maine

unread,
Dec 6, 2010, 4:26:14 PM12/6/10
to
egio <edmondo.g...@gmail.com> wrote:

> Well, you are right, I was thinking to a sort of garbage collection
> by counting the number of pointers referencing to a single memory
> location. I thought that it would have been easier to add this feature
> to allocatable variables.

Fits much better with pointers, I'd say. Allocatable variables always
have only a single "pointer" to them. (The language doesn't call it a
pointer, but that's typically what the underlying implementation looks
like, and you can think of it that way for some purposes). That's pretty
fundamental to allocatables. In a way, I suppose you could call it form
of counted garbage collection, but it is a rather severe subset, as the
count is always either zero or one.

There exist compilers that do garbage collection for Fortran pointers
now, so it can and does fit. Whether one wants to mandate such behavior
in the standard is another question (and one that I'll abstain on).

FX

unread,
Dec 7, 2010, 4:28:41 AM12/7/10
to
> I'm afraid I don't know what you mean by a "smart pointer".

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

--
FX

egio

unread,
Dec 7, 2010, 6:14:59 AM12/7/10
to

Sorry, I may have used a unhappy word, I was just thinking, perhaps
naively, that, as all the paraphernalia to deallocate allocatable
variable is already in place, adding a count garbage collection, (for
a count larger than one, ref R. Maine post) wouldn't be too much
difficult. I was actually asking the opinion of people who had really
built compilers to tell me if I were right or not, if it could be or
not a possible future feature.

The other question is if it could be really useful or not.
If some objects yys need a reference to an object xx I may always pass
the object xx to the yys in an allocatable variable, in this case of
course each object yys gets it's own copy of xx, or I can just pass
them a pointer to xx, in this case I should be sure the xx survive
longer than yys. This, at the end of the day, may be the most sensible
thing to do.

I've worked with Fortran for many years, and I really like if it could
remain on the top for many years in the future.

As an answer to Herrmannsfeldt, I don't know enough of PL/I, but I'll
take a look at it.
In the actual fortran, I think, if you declare a subroutine recursive
every variable is allocated on the stack. The actual data of an
allocatable variable may be on the heap but the address is on the
stack so when you enter the routine you get a new allocatable variable
(that you have to allocate). On the exit from the routine this
variable is automatically deallocated. How everything is affected when
there are internal subprograms (expecially in f200) is another
question, some other on the forum may answer it.
Thanks,

Edmondo Giovannozzi

Arjen Markus

unread,
Dec 7, 2010, 8:35:30 AM12/7/10
to

Many of the benefits (but perhaps not all) listed on that Wikipedia
page
are already available in Fortran:
- Both allocatables and pointers are fully aware of the size and shape
of the
memory they refer to.
- Memory allocated to allocatables is automatically released when it
can no
longer be reached (upon return from a subroutine for instance)

These are all aspects covered by the standard (Fortran 95 at least)
Only for Fortran pointer variables you might argue that the concept of
smart pointers makes some sense.

So, from this point of view I would say that smart pointers in C++ are
a
way to deal with an inherently unsafe design aspect of the language
and
that Fortran has mostly succeeded in avoiding introducing such an
aspect.
(I am formulating this carefully :), I could have used somewhat
stronger
words, but this is a generally polite forum).

Regards,

Arjen

Ian Harvey

unread,
Dec 28, 2010, 8:56:52 PM12/28/10
to
Apologies for the late post, but...

On 08/12/10 00:35, Arjen Markus wrote:
> On 7 dec, 12:14, egio<edmondo.giovanno...@gmail.com> wrote:
>> On 7 Dic, 10:28, "FX"<coud...@alussinan.org> wrote:
>>
>>>> I'm afraid I don't know what you mean by a "smart pointer".
>>
>>> http://en.wikipedia.org/wiki/Smart_pointer
>>

...


>
> Many of the benefits (but perhaps not all) listed on that Wikipedia
> page
> are already available in Fortran:
> - Both allocatables and pointers are fully aware of the size and shape
> of the
> memory they refer to.
> - Memory allocated to allocatables is automatically released when it
> can no
> longer be reached (upon return from a subroutine for instance)
>
> These are all aspects covered by the standard (Fortran 95 at least)
> Only for Fortran pointer variables you might argue that the concept of
> smart pointers makes some sense.
>
> So, from this point of view I would say that smart pointers in C++ are
> a
> way to deal with an inherently unsafe design aspect of the language
> and
> that Fortran has mostly succeeded in avoiding introducing such an
> aspect.
> (I am formulating this carefully :), I could have used somewhat
> stronger
> words, but this is a generally polite forum).

Sure, to a point, but there are whole classes of uses of "smart
pointers" that Fortran doesn't provide convenient facilities for.

- How do you prevent something from being copied in Fortran?

- How do you implement shared ownership in Fortran?

I've wanted to do both of these recently.

There are ways and means for both, but it involves rewriting the
necessary boilerplate code for each type. This is tedious and error
prone.

From my programmers point of view, repetitious code is stuff best left
to libraries. Unfortunately, Fortran's support for the generic or type
agnostic code, that you need to make libraries with these sorts of
"tools", is insufficient unless you want to play platform specific games
or use preprocessing/INCLUDE/IMPLICIT hacks etc.

(For an example - smart pointers in C++ are implemented in accompanying
libraries, because the base language allows (through templates)
type-agnostic code to be written. In fact, the "newer" smart pointers
in the C++ standard library came across from a third party library that
was in common use.)

You can't even in Fortran automatically "template" a procedure around
the kind of an argument, let alone its type. A library writer always
needs to allow manual specification of the kind in some fashion by the
end user. When it comes to kinds the language /nearly/ has all the
necessary hooks to do kind generic program, which is why it is a bit of
a pity that it hasn't quite gotten over the line yet.

(To be clear - I'm not advocating garbage collection for Fortran - while
that is relevant to /some/ of the uses of smart pointers I think the
link is overstated. I'd just like to see better support for generic
programming in the language, that could allow easier implementation of
things like smart pointers, amongst a myriad of other things.)

Arjen Markus

unread,
Dec 29, 2010, 2:54:16 AM12/29/10
to
> things like smart pointers, amongst a myriad of other things.)- Tekst uit oorspronkelijk bericht niet weergeven -
>
> - Tekst uit oorspronkelijk bericht weergeven -

Ah, I was not aware of those uses - yes, support for generic coding is
an interesting
feature. Food for thought, I'd say.

Regards,

Arjen

James Van Buskirk

unread,
Dec 29, 2010, 1:41:20 PM12/29/10
to
"Ian Harvey" <ian_h...@bigpond.com> wrote in message
news:EzwSo.6071$MF5....@viwinnwfe02.internal.bigpond.com...

> From my programmers point of view, repetitious code is stuff best left to
> libraries. Unfortunately, Fortran's support for the generic or type
> agnostic code, that you need to make libraries with these sorts of
> "tools", is insufficient unless you want to play platform specific games
> or use preprocessing/INCLUDE/IMPLICIT hacks etc.

In Fortran you can get write generic code if you use the INCLUDE and
IMPLICIT hack. When I posted an example of this, I was told it was
so ugly that I should switch to another language or wait another
decade until the standard gave us a syntax for template programming
and compilers implemented it.

> You can't even in Fortran automatically "template" a procedure around the
> kind of an argument, let alone its type. A library writer always needs to
> allow manual specification of the kind in some fashion by the end user.
> When it comes to kinds the language /nearly/ has all the necessary hooks
> to do kind generic program, which is why it is a bit of a pity that it
> hasn't quite gotten over the line yet.

In N1830.pdf, Introduction, it says:

"The TYPE keyword can be used to declare entities of intrinsic type."

This could help with generic programming depending on how far it
goes, but I can't see where this is fleshed out in the standard.

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


Beliavsky

unread,
Dec 30, 2010, 6:07:11 AM12/30/10
to
On Dec 29, 12:41 pm, "James Van Buskirk" <not_va...@comcast.net>
wrote:
> "Ian Harvey" <ian_har...@bigpond.com> wrote in message

>
> news:EzwSo.6071$MF5....@viwinnwfe02.internal.bigpond.com...
>
> > From my programmers point of view, repetitious code is stuff best left to
> > libraries.  Unfortunately, Fortran's support for the generic or type
> > agnostic code, that you need to make libraries with these sorts of
> > "tools", is insufficient unless you want to play platform specific games
> > or use preprocessing/INCLUDE/IMPLICIT hacks etc.
>
> In Fortran you can get write generic code if you use the INCLUDE and
> IMPLICIT hack.  When I posted an example of this, I was told it was
> so ugly that I should switch to another language or wait another
> decade until the standard gave us a syntax for template programming
> and compilers implemented it.

Maybe, but if something goes wrong, it should not be too hard to
diagnose and fix the problem,
whereas C++ template compiler error messages are frightening (based on
experiences 10 years ago).

Arjen Markus

unread,
Dec 30, 2010, 6:46:42 AM12/30/10
to
On 29 dec, 19:41, "James Van Buskirk" <not_va...@comcast.net> wrote:
> "Ian Harvey" <ian_har...@bigpond.com> wrote in message

That would be very interesting, as you would not have to special-case
intrinsic types anymore, but the compilers I have access to do not
accept that. Another problem: how would you specify the kind?

Regards,

Arjen

Janus Weil

unread,
Dec 30, 2010, 10:19:02 AM12/30/10
to

> > In N1830.pdf, Introduction, it says:
>
> > "The TYPE keyword can be used to declare entities of intrinsic type."
>
> > This could help with generic programming depending on how far it
> > goes, but I can't see where this is fleshed out in the standard.

The formal definition of this syntactical feature is in R403:

declaration-type-spec is intrinsic-type-spec
or TYPE ( intrinsic-type-spec )
or TYPE ( derived-type-spec )
or CLASS ( derived-type-spec )
or CLASS ( * )


For generic programming what one really needs is unlimited
polymorphism, i.e. CLASS(*).


> That would be very interesting, as you would not have to special-case
> intrinsic types anymore, but the compilers I have access to do not
> accept that.

Well, gfortran does, but only on trunk. The 4.5 release does not
support it.


> Another problem: how would you specify the kind?

As always:

TYPE(integer(8)) :: i
print *,kind(i)
end

Compiled with gfortran 4.6, this spits out the expected value of "8".

Cheers,
Janus

James Van Buskirk

unread,
Dec 30, 2010, 3:09:14 PM12/30/10
to
"Janus Weil" <jayd...@googlemail.com> wrote in message
news:f77c727e-b39e-4944...@i41g2000vbn.googlegroups.com...

>> > In N1830.pdf, Introduction, it says:

>> > "The TYPE keyword can be used to declare entities of intrinsic type."

>> > This could help with generic programming depending on how far it
>> > goes, but I can't see where this is fleshed out in the standard.

> The formal definition of this syntactical feature is in R403:

> declaration-type-spec is intrinsic-type-spec
> or TYPE ( intrinsic-type-spec )
> or TYPE ( derived-type-spec )
> or CLASS ( derived-type-spec )
> or CLASS ( * )

> For generic programming what one really needs is unlimited
> polymorphism, i.e. CLASS(*).

>> That would be very interesting, as you would not have to special-case
>> intrinsic types anymore, but the compilers I have access to do not
>> accept that.

> Well, gfortran does, but only on trunk. The 4.5 release does not
> support it.

Now, that's what I'm talkin' about! But don't you need a couple
more features to put intrinsic types on a par with derived types?

For example, a linked list module template might have declarations:

! start of file: LL_template.i90
implicit none
private
public LLnode
type, public :: LLnode
type(T) data
type(LLnode),pointer :: next
end type LLnode
! [...]
! end of file: LL_template.i90
Then you could instantiate it with:

module LL_mytype
use mytype_mod, only: T => mytype, assignment(=)
include 'LL_template.i90'
end module LL_mytype

To do this with intrinsic types they also need names that exist in
some module so that they can be renamed.

>> Another problem: how would you specify the kind?

> As always:

> TYPE(integer(8)) :: i
> print *,kind(i)
> end

> Compiled with gfortran 4.6, this spits out the expected value of "8".

But what about partial type parameters? Like, could you create a
name for a type like:

character(len=7,kind=*)

say, CHAR7. Then you could declare

CHAR7(1) x
CHAR7(4) y

so that x has type character(7,1) and so on?

Ian Harvey

unread,
Dec 30, 2010, 4:48:49 PM12/30/10
to
On 31/12/10 02:19, Janus Weil wrote:
...

> For generic programming what one really needs is unlimited
> polymorphism, i.e. CLASS(*).
>

That helps, but there's more to it than that.

Unlimited polymorphism is a useful "runtime" feature, but what's lacking
is "compile time" support. Because it is a runtime thing, you end up
with all these SELECT TYPE constructs everywhere, which is a bit silly,
because you know at compile time what sort of type is going to be coming
back at you from the library code.

Conceptually, what's required is something more like TYPE(*), where the
declared type of the argument is inferred at compile time. That's
unlikely to be something that you could easily wriggle into the
language. The parameterised modules approach that I remember reading
about a few years back seem like a reasonable approach - where
essentially the client programmer says to the library module "make me a
whole heap of specialised types and specific procedures where this
placeholder type (or kind) "foo" is actually a "bar". You can do this
now with a preprocessor or the use renaming that's being talked about,
but that sort of approach always makes me feel dirty...

Ian Harvey

unread,
Dec 30, 2010, 4:52:50 PM12/30/10
to
On 30/12/10 22:46, Arjen Markus wrote:
...

> Another problem: how would you specify the kind?

Janus has give the syntax - just to note that this is the same way you
specify the kinds for derived types (so it is nice and consistent), its
just that none of us are used to doing that because very few of us have
compilers that support parametrised derived types...

James Van Buskirk

unread,
Dec 30, 2010, 6:22:08 PM12/30/10
to
"Janus Weil" <jayd...@googlemail.com> wrote in message
news:f77c727e-b39e-4944...@i41g2000vbn.googlegroups.com...

> TYPE(integer(8)) :: i
> print *,kind(i)
> end

> Compiled with gfortran 4.6, this spits out the expected value of "8".

While we're on the subject of f08 features, let me say that I was
happy to discover that gfortran supports the transformational
intrinsics IALL, IANY, and IPARITY. IANY is great for translating
C headers:

# define MY_UGLY_DEFINE (ONE_DEFINE | ANOTHER | YET_MORE | AGAIN)

becomes

integer, parameter, public :: MY_UGLY_DEFINE = iany([ONE_DEFINE, &
ANOTHER,YET_MORE,AGAIN])

There is one minor nit: the title for 8.112 IANY seems to be copied
from that of 8.127 IPARITY. Also the examples are wrong for all
three:

C:\gfortran\clf\iany_test>type test_iall_old.f90
PROGRAM test_iall
INTEGER(1) :: a(2)

a(1) = b'00100100'
a(1) = b'01101010'

! prints 00100000
PRINT '(b8.8)', IALL(a)
END PROGRAM

C:\gfortran\clf\iany_test>gfortran test_iall_old.f90 -otest_iall_old

C:\gfortran\clf\iany_test>test_iall_old
00000000

C:\gfortran\clf\iany_test>type test_iall.f90
PROGRAM test_iall
INTEGER(1) :: a(2)

a(1) = b'00100100'
a(2) = b'01101010'

! prints 00100000
PRINT '(b8.8)', IALL(a)
END PROGRAM

C:\gfortran\clf\iany_test>gfortran test_iall.f90 -otest_iall

C:\gfortran\clf\iany_test>test_iall
00100000

C:\gfortran\clf\iany_test>type test_iany_old.f90
PROGRAM test_iany
INTEGER(1) :: a(2)

a(1) = b'00100100'
a(1) = b'01101010'

! prints 01111011
PRINT '(b8.8)', IANY(a)
END PROGRAM

C:\gfortran\clf\iany_test>gfortran test_iany_old.f90 -otest_iany_old

C:\gfortran\clf\iany_test>test_iany_old
01101010

C:\gfortran\clf\iany_test>type test_iany.f90
PROGRAM test_iany
INTEGER(1) :: a(2)

a(1) = b'00100100'
a(2) = b'01101010'

! prints 01101110
PRINT '(b8.8)', IANY(a)
END PROGRAM

C:\gfortran\clf\iany_test>gfortran test_iany.f90 -otest_iany

C:\gfortran\clf\iany_test>test_iany
01101110

C:\gfortran\clf\iany_test>type test_iparity_old.f90
PROGRAM test_iparity
INTEGER(1) :: a(2)

a(1) = b'00100100'
a(1) = b'01101010'

! prints 10111011
PRINT '(b8.8)', IPARITY(a)
END PROGRAM

C:\gfortran\clf\iany_test>gfortran test_iparity_old.f90 -otest_iparity_old

C:\gfortran\clf\iany_test>test_iparity_old
01101010

C:\gfortran\clf\iany_test>type test_iparity.f90
PROGRAM test_iparity
INTEGER(1) :: a(2)

a(1) = b'00100100'
a(2) = b'01101010'

! prints 01001110
PRINT '(b8.8)', IPARITY(a)
END PROGRAM

C:\gfortran\clf\iany_test>gfortran test_iparity.f90 -otest_iparity

C:\gfortran\clf\iany_test>test_iparity
01001110

Craig Powers

unread,
Dec 30, 2010, 8:06:32 PM12/30/10
to
Ian Harvey wrote:

> Conceptually, what's required is something more like TYPE(*), where the
> declared type of the argument is inferred at compile time. That's
> unlikely to be something that you could easily wriggle into the
> language. The parameterised modules approach that I remember reading
> about a few years back seem like a reasonable approach - where
> essentially the client programmer says to the library module "make me a
> whole heap of specialised types and specific procedures where this
> placeholder type (or kind) "foo" is actually a "bar". You can do this
> now with a preprocessor or the use renaming that's being talked about,
> but that sort of approach always makes me feel dirty...

If it's being designed from scratch, I have to say that I'm very fond of
the way .NET does generics---my specific exposure is via the 2010
edition of VB.NET. The basic declaration is similar to C++, but you can
also impose restrictions on the type (e.g. it must have a default
constructor [sorry, not sure if there's a different term of art in F03
OO], or it must implement a particular interface, or be derived from a
particular base class). (My last experience with C++ is C++/98, so
apologies if I'm overlooking more recent capabilities in that langauge.)

I think there's enough of a history with generic programming in other
languages (and the mistakes that they've made) that there's really no
reason why Fortran's version should not be very sound.

Gary L. Scott

unread,
Dec 30, 2010, 11:17:19 PM12/30/10
to

I hope that's the way they do it...Fortran's design should always try to
be right rather than first. I don't mind compiler vendors trying out
extensions. In fact, I wish it were possible to include extensions that
may not be retained, sort of design try-outs.

Janus Weil

unread,
Dec 31, 2010, 1:12:18 PM12/31/10
to

> While we're on the subject of f08 features, let me say that I was
> happy to discover that gfortran supports the transformational
> intrinsics IALL, IANY, and IPARITY.  IANY is great for translating
> C headers:
>
> # define MY_UGLY_DEFINE (ONE_DEFINE | ANOTHER | YET_MORE | AGAIN)
>
> becomes
>
> integer, parameter, public :: MY_UGLY_DEFINE = iany([ONE_DEFINE, &
>                               ANOTHER,YET_MORE,AGAIN])
>
> There is one minor nit: the title for 8.112 IANY seems to be copied
> from that of 8.127 IPARITY.  Also the examples are wrong for all
> three:

Good catch. I just fixed this. Note, however, that in general
for...@gcc.gnu.org (or the GCC bugzilla database) is a much better
place to report such things ...

Cheers,
Janus

James Van Buskirk

unread,
Jan 2, 2011, 8:47:43 PM1/2/11
to
"Janus Weil" <jayd...@googlemail.com> wrote in message
news:e0a38970-6e8f-4232...@y3g2000vbm.googlegroups.com...


> > There is one minor nit: the title for 8.112 IANY seems to be copied
> > from that of 8.127 IPARITY. Also the examples are wrong for all
> > three:

> Good catch. I just fixed this. Note, however, that in general
> for...@gcc.gnu.org (or the GCC bugzilla database) is a much better
> place to report such things ...

One thing I missed there was that the examples also violated C4102, so
maybe b'00100100' should be replace by int(b'00100100',1).
Also:

C:\gfortran\clf\iany_test>type test_leadz_old.f90
PROGRAM test_leadz
WRITE (*,*) LEADZ(1) ! prints 8 if BITSIZE(I) has the value 32
END PROGRAM

C:\gfortran\clf\iany_test>gfortran test_leadz_old.f90 -otest_leadz_old

C:\gfortran\clf\iany_test>test_leadz_old
31

C:\gfortran\clf\iany_test>type test_leadz.f90
PROGRAM test_leadz
WRITE (*,*) LEADZ(1) ! prints 31 if BITSIZE(1) has the value 32
END PROGRAM

C:\gfortran\clf\iany_test>gfortran test_leadz.f90 -otest_leadz

C:\gfortran\clf\iany_test>test_leadz
31

Janus Weil

unread,
Jan 3, 2011, 4:38:21 AM1/3/11
to
Hi James,

> > > There is one minor nit: the title for 8.112 IANY seems to be copied
> > > from that of 8.127 IPARITY. Also the examples are wrong for all
> > > three:
> > Good catch. I just fixed this. Note, however, that in general

> > fort...@gcc.gnu.org (or the GCC bugzilla database) is a much better


> > place to report such things ...
>
> One thing I missed there was that the examples also violated C4102, so
> maybe b'00100100' should be replace by int(b'00100100',1).

Well, call it a GNU extension ;)

> gfortran-4.6 -std=f2008 test_iall.f90
test_iall.f90:4.30:

a(1) = b'00100100'
1
Error: Extension: BOZ literal at (1) outside a DATA statement and
outside INT/REAL/DBLE/CMPLX
test_iall.f90:5.30:

a(2) = b'01101010'
1
Error: Extension: BOZ literal at (1) outside a DATA statement and
outside INT/REAL/DBLE/CMPLX


Though, admittedly, it does not really count as good style to put such
an extension into an example.

> Also:
>
> C:\gfortran\clf\iany_test>type test_leadz_old.f90
>           PROGRAM test_leadz
>             WRITE (*,*) LEADZ(1)  ! prints 8 if BITSIZE(I) has the value 32
>           END PROGRAM
>
> C:\gfortran\clf\iany_test>gfortran test_leadz_old.f90 -otest_leadz_old
>
> C:\gfortran\clf\iany_test>test_leadz_old
>           31

Hm, it seems people commit these example a bit too carelessly. I'll
take care of it.

Btw, with the rate at which you find bugs in gfortran (the compiler
itself as well as docu), you should think about getting an FSF
assignment and start contributing yourself ;)

Contributing to documentation really is straightforward, and in order
to fix simple bugs in the Fortran front end you also don't need to be
a compiler wizard ...

Cheers,
Janus

card

unread,
Jan 3, 2011, 11:20:05 PM1/3/11
to

I've been implementing reference counting a lot recently in F95/2003
and it's a pretty straightforward pattern to implement. I have a
short ACM SIGPLAN Fortran Forum paper on it (about 2 issues ago) that
discusses the pattern, but in a nutshell it consists of defining two
derived types like so:

type :: Foo_
integer :: refcount = 0
<whatever else shared data you want>
end type

type :: Foo
type (Foo_), pointer :: shared => null()
end type

The user interacts with the the type Foo. You define a few procedures
that initialize, destroy, assign and compare type Foo's (and whatever
else). The initializer would be something like:

subroutine init( this )
type (Foo), intent(in) :: this

call delete( this )
allocate( this % shared )
this % shared % refcount = 1

end subroutine init

The destructor looks like:

subroutine delete( this )
type (Foo), intent(in) :: this

if ( .not. associated( this % shared ) ) return

this % shared % refcount = this % shared % refcount - 1
if ( this % shared % refcount == 0 ) then
deallocate( this % shared )
endif

this % shared % refcount => null()
end subroutine delete

Now, the assignment(=) operation is overloaded to increment the
refcount, something like:

subroutine equals( this, other )
type (Foo), intent(inout) :: this
type (Foo), intent(in) :: other

if ( .not. associated( this % shared, other % shared ) ) then
call delete( this )
if ( associated( other % shared ) then
this % shared => other % shared
this % shared % refcount = this % shared % refcount + 1
endif
endif

end subroutine equals

That's it in a nutshell. So, something like:

program main
type (Foo) :: a, b

call init( a )
b = a

call delete( b )
! a is still defined
call delete( a )
! a is garbage collected
end program

b and a above will point to the same reference. I've also implemented
this in the latest F2003 (gfortran 4.6) with type bound procedures and
polymorphism and the pattern is still straightforward, but I don't
have time to discuss this at the moment.

I've also noticed this thread discussing generics. I've created a
F90/95/2003 templater in Python and there is also an ACM Fortran Forum
article in the same issue I mentioned above. I know it's a
preprocessor, but it certainly can give the experts here something to
play with in terms of design. It is fully functioning and modeled
after C++ templates. It also comes with a library of standard
template containers already and implementing the aforementioned
reference counting pattern. The templater allows for default template
parameters as well as recursive instantiations. For example:

template <class __FOO__, class __BAR__=integer>
module class_Something

AutoUse
end AutoUse

type :: Something
__FOO__ :: my_foo
__BAR__ :: my_bar
end type

end module

program main

AutoUse
end AutoUse

type (Something<integer>) :: a
type (Something<real,real>) :: b
type (Something<Something<real>,Something<integer>>) :: c

end program

So you get the idea of default and recursive definitions. There's a
lot implemented. The website is:

http://blockit.sourceforge.net

The Wiki has some examples. It's just me an one other developer doing
it in our spare time, so we don't have all the documentation we would
like and are behind.

-David

0 new messages