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

optional routine arguments

132 views
Skip to first unread message

LC's No-Spam Newsreading account

unread,
May 8, 2009, 6:45:48 AM5/8/09
to
I started experimenting with some fancy f95 features I never used.
For instance optional arguments.

I wrote this little test program, but it does not behave as expected.
In both calls it says the third argument is present (assuming value 0
when it is not),i.e. present(k) returns .true.

Compiler is ifort 8.1 (under linux)

call sub(1,2)
call sub(1,2,3)
end
subroutine sub(i,j,k)
optional k
intrinsic present
write(*,*)' 3 presence flag ',present(k)
write(*,*)' 1st arg ',i
write(*,*)' 2nd arg ',j
if (present(k)) then
write(*,*)' 3rd arg ',k
else
write(*,*)' 3rd arg is absent'
endif
return
end

--
----------------------------------------------------------------------
nos...@mi.iasf.cnr.it is a newsreading account used by more persons to
avoid unwanted spam. Any mail returning to this address will be rejected.
Users can disclose their e-mail address in the article if they wish so.

paul.rich...@gmail.com

unread,
May 8, 2009, 7:26:52 AM5/8/09
to
On May 8, 12:45 pm, LC's No-Spam Newsreading account
<nos...@mi.iasf.cnr.it> wrote:

If it's any consolation, your code as posted gives with a fairly
vintage gfortran

$ gfortran --version
GNU Fortran (4.3.2-tdm-2 mingw32) 4.3.2
Copyright (C) 2008 Free Software Foundation, Inc.

GNU Fortran comes with NO WARRANTY, to the extent permitted by law.
You may redistribute copies of GNU Fortran
under the terms of the GNU General Public License.
For more information about these matters, see the file named COPYING


richapa@F4E-LS-042 /tmp
$ ./a
3 presence flag F
1st arg 1
2nd arg 2
3rd arg is absent
3 presence flag T
1st arg 1
2nd arg 2
3rd arg 3

Cheers

Paul

Ian Bush

unread,
May 8, 2009, 7:47:54 AM5/8/09
to
On 8 May, 11:45, LC's No-Spam Newsreading account

<nos...@mi.iasf.cnr.it> wrote:
> I started experimenting with some fancy f95 features I never used.
> For instance optional arguments.
>
> I wrote this little test program, but it does not behave as expected.
> In both calls it says the third argument is present (assuming value 0
> when it is not),i.e. present(k) returns .true.
>
> Compiler is ifort 8.1 (under linux)

Rarely use ifort, but I'm pretty sure that's quite old.

>
>           call sub(1,2)
>           call sub(1,2,3)
>           end
>           subroutine sub(i,j,k)
>           optional k
>           intrinsic present
>           write(*,*)' 3 presence flag ',present(k)
>           write(*,*)' 1st arg ',i
>           write(*,*)' 2nd arg ',j
>           if (present(k)) then
>             write(*,*)' 3rd arg ',k
>           else
>             write(*,*)' 3rd arg is absent'
>           endif
>           return
>           end
>

Firstly I very strongly recommend that the first fancy f95 ( actually
f90 ) feature to use is Implicit None.

OK, once you've got that done for optional arguments you need an
interface in scope at the calling point. In fact for all of the "new"
features to do with invoking subprograms that I can think of
immediately you need an interface in scope at the calling point. So
for your code this becomes

Implicit None
Interface
Subroutine sub( a, b, c )
Implicit None
Integer, Intent( In ) :: a
Integer, Intent( In ) :: b
Integer, Intent( In ), Optional :: c
End Subroutine sub
End Interface


call sub(1,2)
call sub(1,2,3)
end
subroutine sub(i,j,k)

Implicit None
Integer, Intent( In ) :: i
Integer, Intent( In ) :: j
Integer, Intent( In ), Optional :: k


intrinsic present
write(*,*)' 3 presence flag ',present(k)
write(*,*)' 1st arg ',i
write(*,*)' 2nd arg ',j
if (present(k)) then
write(*,*)' 3rd arg ',k
else
write(*,*)' 3rd arg is absent'
endif
return
end

If I run the above I get

3 presence flag F
1st arg 1
2nd arg 2
3rd arg is absent
3 presence flag T
1st arg 1
2nd arg 2
3rd arg 3

However the above is a bit misleading in the sense that in reality it
is very, very rare that you have to write an interface like the one
above. Why ? Because if you use the modern features of contained
subprograms or modules you get the interface for free ! So a more
modern way to test the above would be

Module test_optional
Implicit None
Contains
Subroutine sub(i,j,k)
Integer, Intent( In ) :: i
Integer, Intent( In ) :: j
Integer, Intent( In ), Optional :: k
Intrinsic present
Write(*,*)' 3 presence flag ',Present(k)
Write(*,*)' 1st arg ',i
Write(*,*)' 2nd arg ',j
If (Present(k)) Then
Write(*,*)' 3rd arg ',k
Else
Write(*,*)' 3rd arg is absent'
Endif
Return
End Subroutine sub
End Module test_optional

Program t
Use test_optional
Implicit None
Call sub(1,2)
Call sub(1,2,3)
End Program t

and I get the same output as above.

Interfaces are great. Not only do they enable lots of nice new stuff,
they also ensure that arguments match - i.e. your program will not
even compile if you have an argument mismatch ! How many times has
that been a bug in F77 programs ?

Hope this helps,

Ian

LC's No-Spam Newsreading account

unread,
May 8, 2009, 8:19:05 AM5/8/09
to
On Fri, 8 May 2009, paul.rich...@gmail.com wrote:

> If it's any consolation, your code as posted gives with a fairly

> vintage gfortran [... the expected behaviour ...]

Thanks. I cannot test gfortran on my machine for a GLIBC
incompatibility. I had installed on-the-fly a 64-bit version on another
"borrowed" machine (when I did some benchmarking ifort, g95, gfortran)
but that was in a scratch area and is now gone and I would like to avoid
the fuss of reinstalling, so your test is really useful.

I had a definite preference so far for ifort for speed and for handling
legacy f77 code.

I tried g95 instead of ifort. Gives a "Warning (154): Inconsistent
number of arguments in reference to 'sub' at (1) and (2)" but compiles
and runs with the same faulty result as ifort

3 presence flag T <- wrong


1st arg 1
2nd arg 2

3rd arg 0 <- wrong


3 presence flag T
1st arg 1
2nd arg 2
3rd arg 3

LC's No-Spam Newsreading account

unread,
May 8, 2009, 9:04:12 AM5/8/09
to
On Fri, 8 May 2009, Ian Bush wrote:
> On 8 May, 11:45, LC's No-Spam Newsreading account

>> Compiler is ifort 8.1 (under linux)


> Rarely use ifort, but I'm pretty sure that's quite old.

Not intending to upgrade (compiler or OS) until I replace hardware :-)
Hope at the end of the year.

Anyhow that ifort was great for speed and support to f77 legacy code.

[16 lines of my original code snipped]

> Firstly I very strongly recommend that the first fancy f95 ( actually
> f90 ) feature to use is Implicit None.

implicit none (or some of its variants) did exist as a compiler
extension to f77 since at least 16 years. Actually, because of its
variants, I always preferred to use an equivalent compiler switch (-u on
most Unixes, something else on VMS - yes I'm that old and more :-)) and
I regularly do for production programs.

For short test programs I think it's simpler to use the good old I-N
rule :-)

> In fact for all of the "new" features to do with invoking subprograms
> that I can think of immediately you need an interface in scope at the
> calling point. So for your code this becomes

[28 lines of code with explicit interface snipped]

> If I run the above I get [what expected]

I confirm my old ifort gets the correct output too !

> in reality it is very, very rare that you have to write an interface
> like the one above. Why ? Because if you use the modern features of
> contained subprograms or modules

[25 lines of code with module snipped]

> and I get the same output as above.

me too

> Interfaces are great. Not only do they enable lots of nice new stuff,
> they also ensure that arguments match - i.e. your program will not
> even compile if you have an argument mismatch ! How many times has
> that been a bug in F77 programs ?

Well, I knew of INTENT, INTERFACE and MODULE, and they were in the list
among the next cans-of-worms to be opened.

I might appreciate the usage of INTENT to prevent mistakes like passing
a constant as an argument which is going to get modified in a
subroutine, but I'm not sure I'd like to be "coached" with all match
checking (e.g. in the way Java does or beyond). Actually there are cases
in which I would not want even type checking (I have for instance a
legacy routine which does byteswapping for both a REAL*4 and INTEGER*4,
and another lot of telemetry handling routines relying on EQUIVALENCE
...)

I might appreciate the usage of INTERFACE for adding "fancy types" (I
was thinking e.g. of one which does error propagation when doing algebra
on a quantity +/- error) ... but I think that to be forced to use one in
all cases would be an excess of verbosity (compare my 16 lines of code
with your 28) ... I feel aestetically uneasy with them (even with all
the lot of :: statements).

MODULES was the last can-of-worms I was going to try, mainly because
I'm used to things like COMMON blocks, BLOCK DATA, routines rarely in
the same source file, and usually in .a or .so libraries, and I'm not
sure to understand who manages modules (the compiler or the linker or it
depends ?)

So I tried another smaller can-of-worms, i.e. "internal subprograms",
which I read about, but could not understand the difference with the
good old way to keep a routine in the same source file as the main (I
confess I use that very rarely ... if I want to override a library
routine with a temporary test variant, or in the same source as a
routine, if the second routine is called ONLY and ALWAYS by the first)

Anyhow this 21-line example with no interfaces and no modules, but just
a CONTAINS statement, gives the correct output too

Program t


Implicit None
Call sub(1,2)
Call sub(1,2,3)

Contains
Subroutine sub(i,j,k)
Integer, Intent( In ) :: i
Integer, Intent( In ) :: j
Integer, Intent( In ), Optional :: k
Intrinsic present
Write(*,*)' 3 presence flag ',Present(k)
Write(*,*)' 1st arg ',i
Write(*,*)' 2nd arg ',j
If (Present(k)) Then
Write(*,*)' 3rd arg ',k
Else
Write(*,*)' 3rd arg is absent'
Endif
Return
End Subroutine sub

End Program t

I could even chop off lines 1,2,7,8 and 10 (and replace the last
statement with a plain END) ... and the resulting 16 lines of code (as
many as the original ones) do work perfectly.

So it looks like that it is CONTAINS which makes the difference ! At
least for ifort. Apparently, as somebody else tested, gfortran is less
picky and works with my original (simpler-to-read) code ...

LC's No-Spam Newsreading account

unread,
May 8, 2009, 9:24:36 AM5/8/09
to
On Fri, 8 May 2009, LC's No-Spam Newsreading account wrote:

> So it looks like that it is CONTAINS which makes the difference ! At
> least for ifort.

did some more tests ...

If I put the main and the routine in two different source files and
compile as ifort main.f90 sub.f90 .... it does NOT work (as if they were
in the original single code file)

If I do ifort -c sub.f90 and then ifort main.f90 sub.o it does NOT work
as well.

If instead I put your original main and module in two separate source
files, and either compile both f90 at same time, or compile the module
into a .o first and then compile the main source and the .o, everything
works.

Does this mean I have to wrap all library routines within a MODULE ?
And explicitly declaring the USE in the caller ?

Should the job of resolving references not be an (automatized) task for
the linker-loader ONLY ? (actually a colleague of mine spent a lot of
time after my instigation to write a tool which reads a loader map and
wrote Makefiles where the dependencies were from a main to the source of
the routines called, and not to the .a library ... even if the invidual
.o files were not kept)

Ian Bush

unread,
May 8, 2009, 9:38:00 AM5/8/09
to
On May 8, 2:04 pm, LC's No-Spam Newsreading account

<nos...@mi.iasf.cnr.it> wrote:
> On Fri, 8 May 2009, Ian Bush wrote:
> > On 8 May, 11:45, LC's No-Spam Newsreading account
> >> Compiler is ifort 8.1 (under linux)
> > Rarely use ifort, but I'm pretty sure that's quite old.
>
> Not intending to upgrade (compiler or OS) until I replace hardware :-)
> Hope at the end of the year.
>
> Anyhow that ifort was great for speed and support to f77 legacy code.
>
> [16 lines of my original code snipped]
>
> > Firstly I very strongly recommend that the first fancy f95 ( actually
> > f90 ) feature to use is Implicit None.
>
> implicit none (or some of its variants) did exist as a compiler
> extension to f77 since at least 16 years. Actually, because of its
> variants, I always preferred to use an equivalent compiler switch (-u on
> most Unixes, something else on VMS - yes I'm that old and more :-))

Yeah, same here. I was only making the point that it became standard
only in f90.

SNIP!

>
> > Interfaces are great. Not only do they enable lots of nice new stuff,
> > they also ensure that arguments match - i.e. your program will not
> > even compile if you have an argument mismatch ! How many times has
> > that been a bug in F77 programs ?
>
> Well, I knew of INTENT, INTERFACE and MODULE, and they were in the list
> among the next cans-of-worms to be opened.
>
> I might appreciate the usage of INTENT to prevent mistakes like passing
> a constant as an argument which is going to get modified in a
> subroutine, but I'm not sure I'd like to be "coached" with all match
> checking (e.g. in the way Java does or beyond).

Beg to differ. More time is spent debugging than writing the code in
the first place, so anything to help the latter is worth it, even it
it impacts a bit on the former. Hence I stick all the warning flags I
can find on the compile line and only rarely accept new code that
causes any warning to be issued on any of the compilers I use to test
the code, I use whatever the language provides to help diagnose
potential bugs at compiler time rather than debug, and I stick to the
standard as closely as I can ( some libraries make this occasionaly
difficult ).

> Actually there are cases
> in which I would not want even type checking (I have for instance a
> legacy routine which does byteswapping for both a REAL*4 and INTEGER*4,
> and another lot of telemetry handling routines relying on EQUIVALENCE
> ...)
>

Granted, legacy code has its own difficulties.

> I might appreciate the usage of INTERFACE for adding "fancy types" (I
> was thinking e.g. of one which does error propagation when doing algebra
> on a quantity +/- error) ... but I think that to be forced to use one in
> all cases would be an excess of verbosity (compare my 16 lines of code
> with your 28) ... I feel aestetically uneasy with them (even with all
> the lot of :: statements).

Disagree for the reasons above - I can accurately type at 60 words a
minute, what's a few extra characters to cut down on debugging time ?

SNIP !

>
> Anyhow this 21-line example with no interfaces and no modules, but just
> a CONTAINS statement, gives the correct output too

Yep, that because again, just as for the module case, you get the
interface for free,
and because there is an interface in scope at the calling point it
works, just as for the module case.

Snip code.

>
> So it looks like that it is CONTAINS which makes the difference ! At
> least for ifort. Apparently, as somebody else tested, gfortran is less
> picky and works with my original (simpler-to-read) code ...
>

But without the interface, either writen out explicitly or obtained
for free by use of a module or a conatained subprogram, it isn't
standard fortran and so, as you have found, quite likely not to work
everywhere, and even if it does appear to work it may not be
consistent.

Ian

Steve Lionel

unread,
May 8, 2009, 10:36:11 AM5/8/09
to
LC's No-Spam Newsreading account wrote:

> So it looks like that it is CONTAINS which makes the difference ! At
> least for ifort. Apparently, as somebody else tested, gfortran is less
> picky and works with my original (simpler-to-read) code ...

Your original code is not legal Fortran, because it lacks the explicit
interface for a routine with optional arguments. If it "works" for you
now with some compiler, it may not work later. The problem is that the
compiler has no way to know that it needs to pass something special to
indicate that you omitted k. The usual scheme for that is to pass an
address of zero. Without a visible interface, the compiler will pass
two arguments and the third is random data. If you're lucky, it's zero,
but it might be garbage on the stack and would fool the PRESENT call.

Current Intel Fortran (11.0) with interface checking on gives, for your
original code:

test.f90(2): warning #8055: The procedure has a dummy argument that has
the ALLOCATABLE, ASYNCHRONOUS, OPTIONAL, POINTER, TARGET, VALUE or
VOLATILE attribute. Required explicit interface is missing from original
source. [3]
call sub(1,2,3)
----------------------^

Your revised version is legal, though the declaration of PRESENT as
INTRINSIC is not required here.

--
Steve Lionel
Developer Products Division
Intel Corporation
Nashua, NH

For email address, replace "invalid" with "com"

User communities for Intel Software Development Products
http://software.intel.com/en-us/forums/
Intel Fortran Support
http://support.intel.com/support/performancetools/fortran
My Fortran blog
http://www.intel.com/software/drfortran

LC's No-Spam Newsreading account

unread,
May 8, 2009, 11:46:11 AM5/8/09
to
On Fri, 8 May 2009, Steve Lionel wrote:

Great to find an (additional) helpful reply from a person which was so
helpful back in old DEC times !

> LC's No-Spam Newsreading account wrote:
>
>> So it looks like that it is CONTAINS which makes the difference !

> Your original code is not legal Fortran, because it lacks the explicit

> interface for a routine with optional arguments.

which is made clear by your diagnostics

> test.f90(2): warning #8055: The procedure has a dummy argument that has the
> ALLOCATABLE, ASYNCHRONOUS, OPTIONAL, POINTER, TARGET, VALUE or VOLATILE
> attribute. Required explicit interface is missing from original source.

So the answer to the question in my "more tests" posting


" Does this mean I have to wrap all library routines within a MODULE ?
And explicitly declaring the USE in the caller ?"

is "I shall use an explicit interface **only** if I use ALLOCATABLE,
ASYNCHRONOUS, OPTIONAL, POINTER, TARGET, VALUE or VOLATILE" ?

Is this correct ?

This was not clear to me reading Metcalf, Reid and Cohen which is
presently my sort-of-reference. Either it is not written there, or I
did not notice it. All my legacy code worked without interfaces.

> Without a visible interface, the compiler will pass two arguments and
> the third is random data. If you're lucky, it's zero, but it might be
> garbage on the stack

... as it used to be in good (?) old times :-)

> Your revised version is legal, though the declaration of PRESENT as
> INTRINSIC is not required here.

In fact it did work even if I stripped that (and other stuff) out,
as I wrote at the end of my post without showing the code.
I was in doubt I had to declare PRESENT explicitly INTRINSIC or
LOGICAL to force the correct type.

Richard Maine

unread,
May 8, 2009, 12:41:54 PM5/8/09
to
LC's No-Spam Newsreading account <nos...@mi.iasf.cnr.it> wrote:

> MODULES was the last can-of-worms I was going to try...

I recommend exactly the opposite - that modules should be one of the
first new f90 features tried. Certainly not the very first; heck the
large majority of allegedly "f77" programs actually already use features
that were not standardized until f90, so those are the "first". But
because they were so widely adopted as extensions to f77, many people
would say that they didn't "count" as f90 features.

But when you start using features that are more new to f90, you will
find that very many of them are much simpler with modules. If you try to
use them without modules, you will be forced into err-prone and
complicated messes that obscure them.

Optional arguments are one such feature that works best with modules. In
fact, pretty much anything that is new to f90 and has to do with
invoking procedures would fall in this category.

If you habitually put all of your procedures in modules, then optional
arguments (along with many other things) will work. If your procedures
aren't in modules, then you will need to remember to write interface
bodies, which are laborious, verbose, error-prone, and all kinds of
other bad things. If you go down that path, it won't take long to
convince yourself that optional arguments are a mess. What is actually a
mess is the workaround needed to avoid using modules.

Failing to have an explicit interface (which modules give you
automatically) is very high on the list of frequent answers to problems
people send to this newsgroup. It is high enough that the subject line
of your post was sufficient for me to guess (correctly) that this was
likely the problem with your code before I even read the body o fthe
posting.

(Internal procedures are also an option, but they have relatively
limitted utility and mostly only fit smaller problems.)

What I recommend avoiding is interface bodies. There are a few cases
where they are useful, but those are in the distinct minority. They
should be the last option that you consider as a way to provide an
explicit interface - not the first one.

I suppose I should mention though, since you commented that you
generally avoid implicit none, that the problems of implicit typing are
exacerbated by using modules because you then can't tell whether
something is impicitly typed or imported from a module. Add host
association to the mix and you get some really nasty stuff. I suppose
that religiously used compiler switches to disable implicit typing would
also do the job; there was a time when I used such styles, but that's in
the past. You won't find any compiler - not one - that supports things
like the f90 form of optional arguments but doesn't support implicit
none. You'd probably have to work pretty hard to find even an f77
compiler that you could still use today and that didn't support implicit
none; that one is at least possible, but I predict it would be a bit of
work.

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

Steve Lionel

unread,
May 8, 2009, 1:57:20 PM5/8/09
to
LC's No-Spam Newsreading account wrote:

> So the answer to the question in my "more tests" posting
> " Does this mean I have to wrap all library routines within a MODULE ?
> And explicitly declaring the USE in the caller ?"
>
> is "I shall use an explicit interface **only** if I use ALLOCATABLE,
> ASYNCHRONOUS, OPTIONAL, POINTER, TARGET, VALUE or VOLATILE" ?
>
> Is this correct ?

Richard Maine has a long post with good advice I agree with. My
position is that an explicit interface should ALWAYS be available -
doing so cuts down on errors and lets you get your application done (as
in working correctly) sooner. It also lets you take full advantage of
modern Fortran features without having to decide whether or not an
interface is needed.

How you provide those explicit interfaces largely depends on the
structure of your application. Best practice is to group sets of
related routines in a MODULE and USE that module from elsewhere in the
program. Note that you DON'T add the USE within the module to get at
other module-level things in the same module - they're already taken
care of.

If you have a routine that is used by only one other routine, it may be
best to make that a CONTAINed procedure - again, that creates the
explicit interface.

The least desirable method is to write INTERFACE blocks for your Fortran
routines. This duplicates work and is error-prone.

I wrote two articles back in my CVF days that are relevant to this
discussion:

http://software.intel.com/en-us/forums/intel-visual-fortran-compiler-for-windows/topic/41911/reply/12569/
talks about use of OPTIONAL arguments.
http://software.intel.com/en-us/forums/intel-visual-fortran-compiler-for-windows/topic/41911/reply/12572/
talks about explicit interfaces

LC's No-Spam Newsreading account

unread,
May 11, 2009, 5:31:47 AM5/11/09
to
On Fri, 8 May 2009, Steve Lionel wrote:

> I wrote two articles back in my CVF days that are relevant ...

Read and bookmarked, thanks !

Your suggested order of preference seems very clear and sensible, and
satisfies my aesthetic sense :-)

> Best practice in a MODULE

> If you have a routine that is used by only one other routine, it
> may be best to make that a CONTAINed procedure

> The least desirable method is to write INTERFACE blocks for your


> Fortran routines. This duplicates work and is error-prone.

> Richard Maine has a long post with good advice I agree with.

I will continue the discussion in a reply to it.

LC's No-Spam Newsreading account

unread,
May 11, 2009, 8:16:00 AM5/11/09
to
On Fri, 8 May 2009, Richard Maine wrote:
> LC's No-Spam Newsreading account <nos...@mi.iasf.cnr.it> wrote:

>> MODULES was the last can-of-worms I was going to try...
>
> I recommend exactly the opposite - that modules should be one of the

> first new f90 features tried. Certainly not the very first [i.e.
excluding widely adopted extensions to f77]

Oh, yes, the "widely adopted extensions" are those I de facto tested
already compiling and using my legacy code.

I got the impression that modules were something essentially
replacing/improving things like COMMON and BLOCK DATA (which together
with EQUIVALENCE I use regularly though in few specific points of my
legacy code). I was going to give priority to the "silly little easy
new features" (OPTIONAL was in this list), or to important thing like
ALLOCATE (in the legacy code I have since ages my own jacket routines
to calloc) ... now I realize interfaces are related to modules,
and I'll need interfaces for allocatable too.

> If you habitually put all of your procedures in modules, then optional
> arguments (along with many other things) will work.

Optional arguments were not really high in my priority list, I am not
sure even if I ever emulated them with some of the good old tricks in
serious programs. I was just writing down a comparison list of
features in various languages and optional arguments came in (I do
occasionally use them in IDL)

Anyhow it looks that your suggestion matches the one by Steve Lionel,
i.e.:

- use MODULEs as first choice
- Internal procedures as option for smaller problems
- avoid interface bodies

As I said, aesthetically I like it. I wonder how that fits my
established (since a looong time "-)) work habits "per package". I would
be really reluctant to abandon them or change them in a revolutionary
way :

- I do keep ALL main program source files in a source directory
e.g. source/prog1.f source/prog2.f

- I do keep MOST library routines each one in its individual source
file in per-library directories e.g. libsource/lib1/sub1.f
libsource/lib1/sub2.f libsource/lib2/suba.f etc.
A package may have 5 to 10 libraries.

- both kind of sources may make reference to include files which
reside in a SINGLE separate directory e.g. include/pippo.inc (the
sources use a pathless statement INCLUDE 'pippo.inc')

- my "configuration scripts" set the names of the source, libsource,
include (as well as bin, lib and temp directory ... the .o files
go in the temp area). Additionally I have "per family" one-liner
config files which are essentially the list of -l switches.
I have two main script. One is called as "complib libname member"
or "complib libname all" and compiles, ar and ranlib one or all
the members of a library. The other one compiles and links a main
vs its required libraries.

During development I use those scripts. At the end I have a tool
which generates a makefile with dependencies set up in a peculiar
though comfortable way (i.e. a main executable depends on the main
source, the sources of the library routines it calls - NOT THE
ENTIRE LIBRARY - and the include files referred; a library depends
on its source members, which in turn depends on the include files
referred).

- there is no place in the above scheme for "permanent" .o files nor
for routine .f sources which are not in a library.

- Somewhat less than 40% of the main programs contain one or more
routine which is called only by them and is not in a library. These
makes good candidates for the CONTAINS statement.

- only 6% of the library routines contain one or more little routine
called only by them (so far compiled and relocated together),
similarly candidates for the CONTAINS statement.

Now I wonder how modules enter the above scheme.

On one hand if I'd make a single module source file which contains
(CONTAINs) all the routines in a library, it seems to me to go back to
the very old times of HP RTE 6-VM when I used to have one single source
file per library ... but I wonder if this will be efficient from the
point of view of ld ... what will be the member of the .a library ? one
member per routine (as in my current scheme with the 6% exception) or
one mega-block for the entire library always relocated with a main
calling even just a single tiny routine ?

Conversely if I'd make a module per routine (to benefit of the
"automatic" interface), I presume I'd have to declare explicitly to USE
all (and only) the modules I need, which is not forcing manually the
compiler to do something the loader should do automatically ?


..........................................................................

> I suppose I should mention though, since you commented that you
> generally avoid implicit none,

On the contrary, I type explicitly ALL MY variables in MY SERIOUS
programs. I use the good old I-N rule only when compiling source files
supplied by other people (and assumed tested by them), and when
compiling 10-line test programs. But ...

> I suppose that religiously used compiler switches to disable implicit
> typing would also do the job;

... yes, that's exactly my approach. I systematically use the -u switch
together with a bunch of other options. These are usually kept in some
environment set up sourcing a "config file" that my compilation scripts
use. Since I usually have such a config file per package or library, -u
is automatically set for all my main programs and main libraries, and
unset only for "externally supplied" libraries. Or in the quick tests I
compile with ifort (and not my scripts) and run as a.out :-)

> You won't find any compiler that doesn't support implicit none.

If I remind when all this started there was at least a Sun compiler
which used IMPLICIT ANY instead of IMPLICIT NONE. Not used it for ages.

Richard Maine

unread,
May 11, 2009, 12:35:09 PM5/11/09
to
LC's No-Spam Newsreading account <nos...@mi.iasf.cnr.it> wrote:

> On Fri, 8 May 2009, Richard Maine wrote:
> > LC's No-Spam Newsreading account <nos...@mi.iasf.cnr.it> wrote:

> > I recommend... - that modules should be one of the


> > first new f90 features tried.

> As I said, aesthetically I like it. I wonder how that fits my

> established (since a looong time "-)) work habits "per package". I would
> be really reluctant to abandon them or change them in a revolutionary
> way :
>
> - I do keep ALL main program source files in a source directory
> e.g. source/prog1.f source/prog2.f
>
> - I do keep MOST library routines each one in its individual source
> file in per-library directories e.g. libsource/lib1/sub1.f
> libsource/lib1/sub2.f libsource/lib2/suba.f etc.

> A package may have 5 to 10 libraries. ...[etc]

Seems to me like it ought to be adaptable, but I'm not going to sit down
and try to work out all the details (which then might not be the way
you'd prefer to do it anyway).

One note of significance is that you can use INCLUDE in conjunction with
modules. That would allow you to make each of your packages a single
module (which I'd probably do), while still keeping the source code for
the individual routines in separate files. But there are other ways to
do the job. (I almost said to "skin the cat", but I'm not at all sure
that saying would be understood globally.)

In fact, INCLUDE is one of those many common f77 extensions that were
finally standardized in f90.

> > You won't find any compiler that doesn't support implicit none.
>
> If I remind when all this started there was at least a Sun compiler
> which used IMPLICIT ANY instead of IMPLICIT NONE. Not used it for ages.

Yes, I recall that one also, but you edited my quote in a way that
leaves that part out. What I said exactly was

>> You won't find any compiler - not one - that supports things

>> like the f90 form of optional arguments but doesn't support implicit
>> none.

My bit about the f90 form of optional arguments (which was relevant in
context) essentially restricted the set of compilers that statement was
talking about to f90 ones. There were some f77 compilers that supported
a form of optional arguments, but that form that was significantly
different from the later f90 one. You can't do anything much like the
f90 form (or anyway, you can't do it with even half acceptable
performance) without something like an explicit interface, and you just
didn't find that kind of thing as an f77 extension.

I also said

>> You'd probably have to work pretty hard to find even an f77 compiler
>> that you could still use today and that didn't support implicit
>> none; that one is at least possible, but I predict it would be a bit
>> of work.

That old Sun compiler was one of the ones I was specifically thinking
about. I recall it, but that was quite a while ago. Sun's later f77
compilers added implicit none. I think you'd have to work pretty hard to
find a copy of the Sun compiler old enough to be from before they added
implicit none... and also to find a system it would run on. That
compiler might even have been from before Sun's transition to SPARC,
though I'm not sure about that part.

My first Sun box was a Sun 3/60 (not to be confused with an IBM 360
:-)). I recall being dissappointed when I first got one of my
applications to compile on the machine, but then it seemed to hang. I
left it and went out to lunch to get sustenance for a debugging session,
only to find that it finished while I was gone. It hadn't actually hung,
but was just *VERY* slow. I bit of research finally revealed that by
default the compiler used software floating point emulation. You had to
specifically tell it to use the floating point hardware (apparently
because some of the machines didn't have the hardware, so the compiler
was being conservative about portability). When I turned that switch on,
it sped up by about a factor of 50, if I recall correctly.

0 new messages