Home > Archive > Fortran > March 2004 > Re: unresolved unreferenced external procedures
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
Re: unresolved unreferenced external procedures
|
|
| Robert Corbett 2004-03-27, 12:16 am |
| Richard Maine <nospam@see.signature> wrote in message news:<m1wu5kbssz.fsf@macfortran.local>...
> That sounds to me like it just incorporates the old FIB interp
> instead of being anything new, but I certainly have no interest in
> arguing the point (or whether the interp was or was not a good
> idea).
In some sense, yes, it does.
>
> I'll try to transcribe this particular interp by hand. All typos
> are mine. (But the editorial oddity of asking a "question" by
> making an observation and leaving the reader to infer the question
> part is in the original.)
Thank you.
> P.S. No, I'm not going to manually transcribe the whole FIB.
I wouldn't expect you to. It would be nice if such documents were
available, but I wouldn't expect anyone to volunteer for the task.
> Question:
>
> There appears to be no reason to include the name of a BLOCK
> DATA subprogram in an EXTERNAL statement.
>
> Answer:
>
> The appearance of the name of a BLOCK DATA subprogram in an EXTERNAL
> statement allows a processor to use this information to include the
> BLOCK DATA subprogram in the executable program; otherwise, such
> information must be supplied externally to the Fortran program.
The word "allows" is key.
Sincerely,
Bob Corbett
| |
| Jan C. Vorbrüggen 2004-03-27, 12:16 am |
| > > > I believe that, in spite of its name, the EXTERNAL statement's
[...][color=darkred]
> Well... I don't like thinking of it that way. Seems like a backwards
> way of describing and thinking about it to me. I like to think more
> about what something *IS* instead of about what something is not.
Some years ago, Steve Lionel pointed out that INTENT really defines
what you _cannot_ do with the dummy argument, not what you _can_ do,
and after some consideration, I believe that is the best way of thinking
about it.
> So if you want to concentrate on what external means something
> is not, then you need to add variable to the list - external
> means that something is neither an intrinsic nor a variable.
....which, if you look at the quote at the top again, is exactly what
the poster-before-two said. Given that EXTERNAL can be several things,
I do think the "what-it's-not" way of thinking is easier.
Jan
| |
| Richard Maine 2004-03-27, 12:16 am |
| robert.corbett@sun.com (Robert Corbett) writes:
>
> The word "allows" is key.
I agree. That's most of why I think this whole interp sort of useless
from a portability viewpoint. It doesn't provide the user assurance
that such an EXTERNAL statement will do anything useful. About the
only effect, as far as I can see is to guarantee that the user is
allowed to write an EXTERNAL statement for a BLOCK DATA and the
compiler shouldn't reject that, but whether the compiler does anything
useful with it is another mater, quite up to the vendor.
--
Richard Maine | Good judgment comes from experience;
email: my first.last at org.domain | experience comes from bad judgment.
org: nasa, domain: gov | -- Mark Twain
| |
| Richard Maine 2004-03-27, 12:16 am |
| NNTP-Posting-Host: 130.134.31.78
Mime-Version: 1.0
Content-Type: text/plain; charset=iso-8859-1
Content-Transfer-Encoding: 8bit
X-Trace: ftp2.dfrc.nasa.gov 1079626563 5379 130.134.31.78 (18 Mar 2004 16:16:03 GMT)
X-Complaints-To: usenet@ftp2.dfrc.nasa.gov
NNTP-Posting-Date: 18 Mar 2004 16:16:03 GMT
User-Agent: Gnus/5.0808 (Gnus v5.8.8) XEmacs/21.4 (Informed Management)
Path: kermit!newsfeed-east.nntpserver.com!nntpserver.com!news-out.visi.com!petbe.visi.com!news.octanews.net!chiapp19.algx.com!allegiance!ra.nrl.navy.mil!rcp6.edwards.af.mil!news.dfrc.nasa.gov!not-for-mail
Xref: kermit comp.lang.fortran:80796
Jan C. Vorbrüggen <jvorbrueggen@mediasec.de> writes:
> Given that EXTERNAL can be several things,
> I do think the "what-it's-not" way of thinking is easier.
I still disagree for EXTERNAL, but to each his/her own on such
matters.
In any case, if you do want to think of EXTERNAL as defining what it
is not, you also need to list several things there. It is not
adequate to say that it means "not an intrinsic". At the very least,
you also have to also add "not a variable". Oh, and it also means
"not a module or internal procedure". That last part is not just
academic; we quite regularly help people whose codes don't work
because they have used an external statement for module procedures.
That's all I can think of at the moment. So that's 4 things that it
is not; leave any one of those out and you'll get some cases wrong.
If you are trying to make it easier by ignoring cases that do happen
in practice, then I think you are on the wrong track.
As someone else (Bob?) noted, you have to be a little careful
about even the "not an intrinsic" part. When a dummy argument has
the external attribute, the actual argument *IS* allowed to be an
intrinsic. Or perhaps I might accurately say that it isn't not
an intrinsic? :-)
Yes, the dummy and actual are different things, so you can still think
of the external as meaning that the dummy isn't an intrinsic - just be
careful about the possible misinterpretation. Of course, you have to
be careful about that case anyway; that's why when you list the things
that it is, "dummy argument" is one of the cases you have to list
separately. I think you have to remember how to interpret the dummy
argument case carefully even if you are keeping track of what external
isn't.
--
Richard Maine | Good judgment comes from experience;
email: my first.last at org.domain | experience comes from bad judgment.
org: nasa, domain: gov | -- Mark Twain
| |
| glen herrmannsfeldt 2004-03-27, 12:16 am |
| Richard Maine wrote:
(snip)
> As someone else (Bob?) noted, you have to be a little careful
> about even the "not an intrinsic" part. When a dummy argument has
> the external attribute, the actual argument *IS* allowed to be an
> intrinsic. Or perhaps I might accurately say that it isn't not
> an intrinsic? :-)
Could you explain this a little better? There are a number
of intrinsic functions that are pretty much always generated
inline, MOD is one. Do they supply an external MOD
just for that case?
Putting MOD in an EXTERNAL statement would allow for a
user defined MOD not passed as a dummy argument.
The other case, discussed not so long ago, has to do with
dummy arguments and generics. There is no way for the
compiler to figure out at compile time the type of the
arguments to be applied to a function name passed as a
dummy argument. Are the old, non-generic names still
available for that case? (SIN, DSIN, CSIN, etc.)
-- glen
| |
| Richard Maine 2004-03-27, 12:17 am |
| glen herrmannsfeldt <gah@ugcs.caltech.edu> writes:
> Richard Maine wrote:
>
> Could you explain this a little better? There are a number
> of intrinsic functions that are pretty much always generated
> inline, MOD is one. Do they supply an external MOD
> just for that case?
Only a relatively small number of standard intrinsics can be
passed as actual arguments. See 13.12 of f95 for the list (and
be sure to read the note at the end of the section - I'd have
organized this data as 2 separate tables instead of trying to
combine it all into one table.) Yes, MOD is one of them. And
yes, that means in practice that the compiler has to have a
version that "looks like" an external. In standard-speak it
isn't an external, but in practical implementation, it is going
to look like one (most likely).
Do note that when MOD is passed as an actual argument, it is
only one of the specific versions - namely the one for default
integer; you can't pass generics as arguments. AMOD and DMOD
are also in that table, but you have to use those specific
names.
> The other case, discussed not so long ago, has to do with
> dummy arguments and generics. There is no way for the
> compiler to figure out at compile time the type of the
> arguments to be applied to a function name passed as a
> dummy argument. Are the old, non-generic names still
> available for that case? (SIN, DSIN, CSIN, etc.)
Yes. See the above-cited section. Similar to mod, amod, dmod,
those are the names of specifics. In some cases, the name of
the generic is the same as the name of one of those specifics.
When used as an actual argument, only the specific is passed.
--
Richard Maine | Good judgment comes from experience;
email: my first.last at org.domain | experience comes from bad judgment.
org: nasa, domain: gov | -- Mark Twain
| |
| James Van Buskirk 2004-03-27, 12:17 am |
| "Richard Maine" <nospam@see.signature> wrote in message
news:m1k71ihs81.fsf@macfortran.local...
> Only a relatively small number of standard intrinsics can be
> passed as actual arguments. See 13.12 of f95 for the list (and
> be sure to read the note at the end of the section - I'd have
> organized this data as 2 separate tables instead of trying to
> combine it all into one table.) Yes, MOD is one of them. And
> yes, that means in practice that the compiler has to have a
> version that "looks like" an external. In standard-speak it
> isn't an external, but in practical implementation, it is going
> to look like one (most likely).
What is shocking and non-orthogonal to me is that the standard
mandates some specific intrinsics without mandating their
specific name. Thus you have some specific intrinsics that
for no obvious reason are excluded not by family (like MAX)
but as individuals within a family (like the double precision
complex version of many intrinsics.)
BTW, it's possible to write an interface block for a dummy
argument that can only be associated with an intrinsic
actual argument, but for which no intrinsic exists that
matches the interface block. Do any compilers warn when
this condition exists?
--
write(*,*) transfer((/17.392111325966148d0,6.5794487871554595D-85, &
6.0134700243160014d-154/),(/'x'/)); end
| |
| Richard Maine 2004-03-27, 12:17 am |
| "James Van Buskirk" <not_valid@comcast.net> writes:
> What is shocking and non-orthogonal to me is that the standard
> mandates some specific intrinsics without mandating their
> specific name.
I'm not understanding what you mean by that. The only specifics that
I know are mandated are those listed by name in 13.12, and well, that
lists the mandated specific names. I'm clearly misinterpreting
something about this. (Perhaps I'm supposed to have taken a clue from
the following "Thus", but I couldn't).
The list of specifics shows a lot of inconsistency, I agree. Most of
that list is pretty clearly historical - it is there so that the
things that were legal back in f66 (pre-generics) are still legal.
I don't know how you'd standardize specific names when you don't
even know how many specifics there are (because you don't know
how many real or integer kinds there are).
> BTW, it's possible to write an interface block for a dummy
> argument that can only be associated with an intrinsic
> actual argument, but for which no intrinsic exists that
> matches the interface block. Do any compilers warn when
> this condition exists?
You can? Guess I'll take your word for it.... which isn't to say that
I'm disagreeing, just that I've never thought about it and can't see
why I'd want to either. Seems like a pretty limiting special case,
the list of specific intrinsics being, as noted, pretty small.
--
Richard Maine | Good judgment comes from experience;
email: my first.last at org.domain | experience comes from bad judgment.
org: nasa, domain: gov | -- Mark Twain
| |
| James Van Buskirk 2004-03-27, 12:17 am |
| "Richard Maine" <nospam@see.signature> wrote in message
news:m18yhxj3xg.fsf@macfortran.local...
> I'm not understanding what you mean by that. The only specifics that
> I know are mandated are those listed by name in 13.12, and well, that
> lists the mandated specific names. I'm clearly misinterpreting
> something about this. (Perhaps I'm supposed to have taken a clue from
> the following "Thus", but I couldn't).
We have discussed this before. ABS, for example, is required to
work on double precision complex arguments so there must be at
least the functionality of a specific function that does this for
a standard-conforming Fortran processor, but you can't pass it as
an actual argument to another procedure like you can the other
specific forms of ABS that are mandated to exist by the standard.
Example of code that uses the ineffible CDABS:
! File: wierd_func1.f90
program wierd_func1
implicit none
integer, parameter :: dp = kind(1.0d0)
complex(dp) x
real(dp) pi
pi = 4*atan(1.0_dp)
x = exp(2*pi*(0,1)/5)
write(*,*) ' cdabs(x) = ', abs(x)
end program wierd_func1
! End of file: wierd_func1.f90
Should be standard-conforming and LF95 doesn't say
anything untoward about it. If you want to have
a program that passes CDABS as an actual argument,
however, you have to write a wrapper for it if you
want to be standard-conforming.
> You can? Guess I'll take your word for it.... which isn't to say that
> I'm disagreeing, just that I've never thought about it and can't see
> why I'd want to either. Seems like a pretty limiting special case,
> the list of specific intrinsics being, as noted, pretty small.
Don't just take my word for it. See if any compilers warn about
the following file (compile only, don't link):
! File: wierd_func2.f90
module mytypes
implicit none
type icantbelieveitsnotbutter
integer itsnotnicetofoolwithmothernatur
end type icantbelieveitsnotbutter
end module mytypes
module contains_paradox
use mytypes
implicit none
contains
function paradox(fun,lipids)
interface
elemental function fun(lipids)
use mytypes
implicit none
type(icantbelieveitsnotbutter), intent(in) :: lipids
integer fun
end function fun
end interface
type(icantbelieveitsnotbutter), intent(in) :: lipids(:)
integer :: paradox(size(lipids))
paradox = fun(lipids)
end function paradox
end module contains_paradox
! End of file: wierd_func2.f90
Function paradox in the above requires an actual argument
which is an elemental function that takes a dummy argument
of type(icantbelieveitsnotbutter). Unless I have read
Lahey's documentation incorrectly, that compiler doesn't
supply an intrinsic that takes a dummy argument of this
type. Now, if we try to supply a driver program to call
function paradox:
! File: wierd_func3.f90
module funny
use mytypes
implicit none
contains
elemental function pain(lost_soul)
! pure function pain(lost_soul)
type(icantbelieveitsnotbutter), intent(in) :: lost_soul
integer pain
pain = lost_soul%itsnotnicetofoolwithmothernatu
r
end function pain
end module funny
program wierd_func3
use mytypes
use contains_paradox
use funny
implicit none
type(icantbelieveitsnotbutter) :: lipids(3)
lipids = (/ icantbelieveitsnotbutter(2), &
icantbelieveitsnotbutter(3), &
icantbelieveitsnotbutter(1) /)
write(*,*) paradox(pain,lipids)
end program wierd_func3
! End of file: wierd_func3.f90
LF95 rejects the above, and rightly so. If we comment
out the line that declares function PAIN to be ELEMENTAL
and uncomment the line that declares it to be merely
PURE, it works, but I don't think that should be so.
For example a PURE function can also be RECURSIVE (and
LF95 doesn't squawk when PAIN is here) but an ELEMENTAL
function can't be.
CVF accepts the ELEMENTAL declaration of PAIN in the
above but does warn that it's not standard-conforming
code. If PAIN is downgraded to PURE, CVF rejects the
code. This kind of behavior (different compilers having
different preferences on how to set up a call to a function)
is not what one would expect from good standard-conforming
code, and the root cause is the declaration of a dummy argument
to function paradox as being an elemental function that has
no intrinsic counterpart that could be used as an actual
argument.
I hoped you might be amused by the above example. Does
NAG or Salford generate a warning for wierd_func2.f90?
write(*,*) transfer((/17.392111325966148d0,6.5794487871554595D-85, &
6.0134700243160014d-154/),(/'x'/)); end
| |
| glen herrmannsfeldt 2004-03-27, 12:17 am |
| James Van Buskirk wrote:
> "Richard Maine" <nospam@see.signature> wrote in message
> news:m18yhxj3xg.fsf@macfortran.local...
[color=darkred]
> We have discussed this before. ABS, for example, is required to
> work on double precision complex arguments so there must be at
> least the functionality of a specific function that does this for
> a standard-conforming Fortran processor, but you can't pass it as
> an actual argument to another procedure like you can the other
> specific forms of ABS that are mandated to exist by the standard.
Functions like ABS, even CDABS, are very easy to generate
as inline code, as is MOD. On the other hand, if you wanted
CDABS it wouldn't be hard to write, even with the extra tests
to not overflow in some situations.
-- glen
| |
| Richard Maine 2004-03-27, 12:17 am |
| "James Van Buskirk" <not_valid@comcast.net> writes:
> "Richard Maine" <nospam@see.signature> wrote in message
> news:m18yhxj3xg.fsf@macfortran.local...
>
>
> We have discussed this before. ABS, for example, is required to
> work on double precision complex arguments so there must be at
> least the functionality of a specific function that does this for
> a standard-conforming Fortran processor, but you can't pass it as
> an actual argument to another procedure like you can the other
> specific forms of ABS that are mandated to exist by the standard.
Ah. Ok. I wasn't sure that was what you were referring to. As I
mentioned, this problem seems unsolvable in general. The standard
could define a few more specific specific names...or perhaps I say
particular specific names :-), but how would it define all of them
without knowing how many kinds there are? I suppose one could define
a specific name for every standard intrinsic for every combination of
mandated kinds, but that is still going to seem strange. People would
then wonder why there was a CDABS, but not a CQABS (or whatever name
seems appropriate) on a compiler thaat supports a quad precision. Or
an IHALFABS (that name seems pretty unlikely, I agree, though with a
change of the B to an S, some people might think it an appropriate
thing for me to say :-)) on a compiler that supports a 16-bit integer
in addition to a default 32-bit one. It would also be an awful lot of
names.
Again, the list of specific names is mostly historical. I personally
doubt you will see it extended, as that seems like a dead-end
approach.
[color=darkred]
> function paradox(fun,lipids)
> interface
> elemental function fun(lipids)
....
Hmm. I didn't think you could have an elemental dummy at all.
Going to have to leave in just a minute, so no time to check.
> Function paradox in the above requires an actual argument
> which is an elemental function that takes a dummy argument
> of type(icantbelieveitsnotbutter).
Ok. Well, assuming that it is legal to do such a thing,
that would certainly be how I'd expect it to look.
> Unless I have read
> Lahey's documentation incorrectly, that compiler doesn't
> supply an intrinsic that takes a dummy argument of this
> type.
Umm. There's my problem. Where did "intrinsic" suddenly
come into this? I see that this would require the actual argument
to be an elemental function as you describe, but it seems to me
that you just brought intrinsics up out of the blue. The
keyword "intrinsic" doesn't even appear in the code. Is there
some subtlety by which it is implied? I keep thinking of
commenting that elemental =/ intrinsic, but I have a feeling
that I'm missing something deeper here. Maybe if I took a
little more time to study it...
--
Richard Maine | Good judgment comes from experience;
email: my first.last at org.domain | experience comes from bad judgment.
org: nasa, domain: gov | -- Mark Twain
| |
| James Van Buskirk 2004-03-27, 12:17 am |
| "glen herrmannsfeldt" <gah@ugcs.caltech.edu> wrote in message
news:gAq6c.36337$J05.228154@attbi_s01...
> Functions like ABS, even CDABS, are very easy to generate
> as inline code, as is MOD. On the other hand, if you wanted
> CDABS it wouldn't be hard to write, even with the extra tests
> to not overflow in some situations.
The issue here is different from your perception, and it's
more of a question of program maintainence, as are many of
these orthogonality issues.
Suppose you had a program that use single-precision complex
variables and somewhere in it you had an innocuous command
like:
call sub(carray,cabs)
Now, what happens when you try to change this program to
all work for double precision data? Well, of course you
change the kind type parameter in the module all of your
program units USE so that they all know that all the
constants like 3.14159265358979_wp are promoted and
expressions like cmplx(a,b,wp) will go through and
declarations like comlex(wp), allocatable :: h(:) will
be OK, so there will be only situations where, for example,
your minmax polynomial for sin(x) valid in [0,pi/2] will
need to be changed and usage of specific intrinsics also
will have to be changed. Unfortunately the invocation
of sub above not only has to be edited, but a separate
function that does what the ineffible intrinsic CDABS
will have to be written: something as innocuous as
pure function MY_CDABS(x)
use my_changing_types, only: wp
implicit none
complex(wp), intent(in) :: x
real(wp) MY_CDABS
MY_CDABS = abs(x)
end function MY_CDABS
Now the above is in some ways preferable to the original
in that if wp is flipped back to kind(1.0) the invocation
of sub will still work, but it has two obvious drawbacks:
1) Likely loss of performance if the compiler can't see
and inline MY_CDABS, and
2) it will cause problems if the dummy argument that got
associated with CABS in the original subroutine sub
was used elementally there.
Perhaps this discussion more clearly illustrates what I
mean by 'nonorthogonality'.
--
write(*,*) transfer((/17.392111325966148d0,6.5794487871554595D-85, &
6.0134700243160014d-154/),(/'x'/)); end
| |
| James Van Buskirk 2004-03-27, 12:17 am |
| "Richard Maine" <nospam@see.signature> wrote in message
news:m1vfl1hf1p.fsf@macfortran.local...
> Umm. There's my problem. Where did "intrinsic" suddenly
> come into this? I see that this would require the actual argument
> to be an elemental function as you describe, but it seems to me
> that you just brought intrinsics up out of the blue. The
> keyword "intrinsic" doesn't even appear in the code. Is there
> some subtlety by which it is implied? I keep thinking of
> commenting that elemental =/ intrinsic, but I have a feeling
> that I'm missing something deeper here. Maybe if I took a
> little more time to study it...
I'll leave it to you to see what happens when you try to
compile my example. Don't want to spoil the surprise too much :)
--
write(*,*) transfer((/17.392111325966148d0,6.5794487871554595D-85, &
6.0134700243160014d-154/),(/'x'/)); end
| |
| glen herrmannsfeldt 2004-03-27, 12:17 am |
| Richard Maine wrote:
> "James Van Buskirk" <not_valid@comcast.net> writes:
(snip)
[color=darkred]
> Ah. Ok. I wasn't sure that was what you were referring to. As I
> mentioned, this problem seems unsolvable in general. The standard
> could define a few more specific specific names...or perhaps I say
> particular specific names :-), but how would it define all of them
> without knowing how many kinds there are? I suppose one could define
> a specific name for every standard intrinsic for every combination of
> mandated kinds, but that is still going to seem strange. People would
> then wonder why there was a CDABS, but not a CQABS (or whatever name
> seems appropriate) on a compiler thaat supports a quad precision.
Yes, the IBM compilers that have COMPLEX*32 have CQABS, and other
CQ functions.
> Or
> an IHALFABS (that name seems pretty unlikely, I agree, though with a
> change of the B to an S, some people might think it an appropriate
> thing for me to say :-)) on a compiler that supports a 16-bit integer
> in addition to a default 32-bit one. It would also be an awful lot of
> names.
The PL/I compilers I know have names like that for all the functions.
One might have in one routine an EXTERNAL call to a function that
has the same name as a BUILTIN function in another, so the names
would have to be different. I believe Fortran requires that if you
replace an intrinsic routine, though the use of EXTERNAL, that you
don't call the intrinsic one from another module.
-- glen
| |
| Richard Maine 2004-03-27, 12:17 am |
| glen herrmannsfeldt <gah@ugcs.caltech.edu> writes:
> I believe Fortran requires that if you
> replace an intrinsic routine, though the use of EXTERNAL, that you
> don't call the intrinsic one from another module.
No, that is not the case. In fact, your use of the word "replace" is
misleading here. There is no way to "replace" an intrinsic routine,
through the use of EXTERNAL or anything else. The EXTERNAL just tells
the compiler that, in the current scoping unit, the name in question
is for an external procedure (or a block data or a dummy procedure).
It has no effect at all on any other scoping unit. It does not
replace the intrinsic; the intrinsic is still there and can be used
elsewhere.
Yes, it is perfectly legal for one scoping unit to reference an
external procedure named MOD, another scoping unit to use the
intrinsic mod, and perhaps yet another scoping unit use a local
variable named mod. You just can't do any two of those in the same
scoping unit. (Well, not with the same names anyway - USE with
rename is another matter).
--
Richard Maine
email: my last name at domain
domain: sumertriangle dot net
| |
| glen herrmannsfeldt 2004-03-27, 12:17 am |
| Richard Maine wrote:
> glen herrmannsfeldt <gah@ugcs.caltech.edu> writes:
[color=darkred]
> No, that is not the case. In fact, your use of the word "replace" is
> misleading here. There is no way to "replace" an intrinsic routine,
> through the use of EXTERNAL or anything else. The EXTERNAL just tells
> the compiler that, in the current scoping unit, the name in question
> is for an external procedure (or a block data or a dummy procedure).
> It has no effect at all on any other scoping unit. It does not
> replace the intrinsic; the intrinsic is still there and can be used
> elsewhere.
> Yes, it is perfectly legal for one scoping unit to reference an
> external procedure named MOD, another scoping unit to use the
> intrinsic mod, and perhaps yet another scoping unit use a local
> variable named mod. You just can't do any two of those in the same
> scoping unit. (Well, not with the same names anyway - USE with
> rename is another matter).
"If an intrinsic function name appears in an EXTERNAL statement in a
program unit, that name becomes the name of some external procedure and
an intrinsic function of the same name is not available for reference in
the program unit." from F77.
It is the "program unit" that I forgot about.
The F66 compilers I know name the library routines the same as
the Fortran name, so it would be hard to do that.
-- glen
| |
| Jan C. Vorbrüggen 2004-03-27, 12:17 am |
| > Again, the list of specific names is mostly historical. I personally
> doubt you will see it extended, as that seems like a dead-end approach.
Agreed - but how about a more "modern", a "kind"er approach? That is,
instead of having the actual argument "ABS" - which must be specific at
compile time, and therefore can only be one definite entity - have as the
actual argument "ABS(KIND=whatever)", which allows the compiler to select
the correct specific at compile time based on the same information it used
to select the KINDs of the variables/arrays involved.
Jan
| |
| Jan C. Vorbrüggen 2004-03-27, 12:17 am |
| > Or
> an IHALFABS (that name seems pretty unlikely, I agree, though with a
> change of the B to an S, some people might think it an appropriate
> thing for me to say :-)) on a compiler that supports a 16-bit integer
> in addition to a default 32-bit one. It would also be an awful lot of
> names.
The DEC compilers do just that: they have a systematic naming convention
for all specific intrinsics - except for the cases where the standard mandates
otherwise 8-).
Jan
| |
| Richard Maine 2004-03-27, 12:17 am |
| glen herrmannsfeldt <gah@ugcs.caltech.edu> writes:
> Richard Maine wrote:
....[color=darkred]
> The F66 compilers I know name the library routines the same as
> the Fortran name, so it would be hard to do that.
Hmm. I thought f66 was similar here, but that's not the kind of
thing I would have known the fine points of back when I was coding
in f66. Lets' see...
My! I didn't know that. F66 does have the same kind of rule for
intrinsic functions. See 10.1, and in particular 10.1.7
"The use of an intrinsic function in a program unit does not
preclude the use of the same symbolic name to identify some
other entity in a differemt program unit of that executable
program."
If you might think that means only local variables, but that its
use as an external name might still be prohibitted, see 10.1.1.
Anyway, that part is as I expected, but the complete surprise to me is
8.3.3. Some of the functions that I think of as intrinsics are not so
in f66. Instead they are "basic external functions" that the
processor must supply. Well, that's different. The compiler-provided
EXP, for example, is an external; thus an EXTERNAL statement for it is
not going to have anything to do with using the compiler-provided one
versus one you might have written.
The selection of which compiler-provided functions are classified as
these basic external functions seems.... strange. Mostly they are the
trig, log, sqrt, etc kinds of things. It seeems a bit strange that
CABS is in a different class from ABS, IABS, and DABS, but I suppose
that if you think of CABS as involving a square root, one can make
some sense out of it. But why DMOD is in a different class from
MOD and AMOD... I just can't figure that.
--
Richard Maine | Good judgment comes from experience;
email: my first.last at org.domain | experience comes from bad judgment.
org: nasa, domain: gov | -- Mark Twain
| |
| Richard Maine 2004-03-27, 12:17 am |
| Jan C. Vorbrüggen <jvorbrueggen@mediasec.de> writes:
>
> Agreed - but how about a more "modern", a "kind"er approach? That is,
> instead of having the actual argument "ABS" - which must be specific at
> compile time, and therefore can only be one definite entity - have as the
> actual argument "ABS(KIND=whatever)", which allows the compiler to select
> the correct specific at compile time based on the same information it used
> to select the KINDs of the variables/arrays involved.
There has been at least some discussion along these general lines
somewhere. I'm having trouble recalling whether it was in one of the
170 papers at the last J3 meeting or was a discussion in clf. Whether
it will come to fruition in the near future, I can't predict.
--
Richard Maine | Good judgment comes from experience;
email: my first.last at org.domain | experience comes from bad judgment.
org: nasa, domain: gov | -- Mark Twain
| |
| Richard Maine 2004-03-27, 12:17 am |
| Richard Maine <nospam@see.signature> writes:
> "James Van Buskirk" <not_valid@comcast.net> writes:
>
> You can? Guess I'll take your word for it....
Ah. Ok. Tried your sample code with NAG and then studied the
standard a little. The code compiles and runs correctly with
NAG, with a warning about it being an extension. On studying
the standard...
Guess I don't see any restriction against having an elemental
dummy. I knew there was a restriction against passing elementals
as arguments, but that restriction allows an exception for
intrinsic elementals. I'd always thought of the exception as
allowing you to pass the elemental intrinsic actual to a
nonelemental dummy (which is allowed). If that exception
weren't allowed, then previously standard-conforming code
would suddently have been nonstandard when the intrinsics
were redefined to be elemental.
But I guess you can also pass an intrinsic elemental actual
to an elemental dummy. Just never occured to me to try it,
insomuch as the only elemental actuals allowed are the
intrinsics. I don't think I've ever had an application where
that would have been both useful and sufficient. Once you
allow nonintrinsic elemental actual arguments, it becomes
more widely useful, but that's an extension, as you noted.
So I do see how "intrinsic" comes in, but it is only by
indirect inference. It isn't that the dummy explicitly
requires intrinsics - just that intrinsics happen to be
the only thing that slip through the prohibitions here.
(I hadn't formerly realized that they slipped through.)
I note that when you change the actual to pure instead of
elemental, NAG accepts it without warning (and it still
runs correctly). I agree with you that that isn't conforming.
You are allowed to have an elemental actual (intrinsic only,
but assume an extension for that) with a nonelemental dummy,
but nothing allows a nonelemental actual to go with an
elemental dummy, and it doesn't seem like a natural extension
either. Looks to me just like that's a thing in the interface
that isn't checked by the compiler.
In principle, I suppose it ought to be checked, but it is arcane
enough to not be very high on my list of concerns. I'm not
likely to make that mistake.... since it starts out by having
an elental dummy, which I didn't even realize you could do
at all and still can't imagine doing usefully without an extension.
Don't think I'll bother bugging NAG about the failure to
diagnose it; I've got other things I'd rather see them do.
--
Richard Maine | Good judgment comes from experience;
email: my first.last at org.domain | experience comes from bad judgment.
org: nasa, domain: gov | -- Mark Twain
| |
| glen herrmannsfeldt 2004-03-27, 12:17 am |
| Richard Maine wrote:
(snip)
> Hmm. I thought f66 was similar here, but that's not the kind of
> thing I would have known the fine points of back when I was coding
> in f66. Lets' see...
> My! I didn't know that. F66 does have the same kind of rule for
> intrinsic functions. See 10.1, and in particular 10.1.7
> "The use of an intrinsic function in a program unit does not
> preclude the use of the same symbolic name to identify some
> other entity in a differemt program unit of that executable
> program."
> If you might think that means only local variables, but that its
> use as an external name might still be prohibitted, see 10.1.1.
> Anyway, that part is as I expected, but the complete surprise to me is
> 8.3.3. Some of the functions that I think of as intrinsics are not so
> in f66. Instead they are "basic external functions" that the
> processor must supply. Well, that's different. The compiler-provided
> EXP, for example, is an external; thus an EXTERNAL statement for it is
> not going to have anything to do with using the compiler-provided one
> versus one you might have written.
That was the one I hadn't realized changed in F77.
> The selection of which compiler-provided functions are classified as
> these basic external functions seems.... strange. Mostly they are the
> trig, log, sqrt, etc kinds of things. It seeems a bit strange that
> CABS is in a different class from ABS, IABS, and DABS, but I suppose
> that if you think of CABS as involving a square root, one can make
> some sense out of it. But why DMOD is in a different class from
> MOD and AMOD... I just can't figure that.
On most machines ABS, IABS and MOD should be one or two instructions.
CABS has the square root, and usually some extra work so that the
intermediate doesn't overflow.
The only one I can think of for DMOD is that some machines at
the time had hardware for single precision float, but software
(subroutine calls) for double precision. Otherwise, I would
have thought it would be similar to AMOD, but in any case
more than a few instructions on most machines.
-- glen
| |
| James Van Buskirk 2004-03-27, 12:17 am |
| "Richard Maine" <nospam@see.signature> wrote in message
news:m18yhw1s7v.fsf@macfortran.local...
> In principle, I suppose it ought to be checked, but it is arcane
> enough to not be very high on my list of concerns. I'm not
> likely to make that mistake.... since it starts out by having
> an elental dummy, which I didn't even realize you could do
> at all and still can't imagine doing usefully without an extension.
> Don't think I'll bother bugging NAG about the failure to
> diagnose it; I've got other things I'd rather see them do.
I hope you were at least slightly amused by my example as it
shows one way the standard permits you to paint yourself into
a corner that it doesn't provide you a way of getting out of.
The elemental dummy was not a violation of the standard; it's
just that any attempt to pass a matching actual argument is
nonconforming.
The standard actually seems to forbid some other attempts
that have a purpose: suppose you wanted to require that
anyone who used your subroutine made a keyword call, never
a positional argument call. One way to attempt to do this
would be to define a PRIVATE user-defined type in a module
and make the first argument to a public subroutine be of
that type and OPTIONAL. That way any invocation would have
to be with keywords because the first positional argument
simply can't be constructed. Unfortunately the standard
seems to forbid such a subroutine with an inaccessible dummy
argument to be itself accessible outside the module, or at
least I have seen compilers reject code like that. The
standard is strangely picky about user-defined type
accessibility.
--
write(*,*) transfer((/17.392111325966148d0,6.5794487871554595D-85, &
6.0134700243160014d-154/),(/'x'/)); end
| |
| Richard Maine 2004-03-27, 12:17 am |
| "James Van Buskirk" <not_valid@comcast.net> writes:
> I hope you were at least slightly amused by my example....
Yes.
> Unfortunately the standard
> seems to forbid such a subroutine with an inaccessible dummy
> argument to be itself accessible outside the module, or at
> least I have seen compilers reject code like that. The
> standard is strangely picky about user-defined type
> accessibility.
That strange pickiness is gone... but I get about
exactly when without checking. Probably not until f2003.
I recall getting rid of those silly restrictions a long
time ago... but then the first work on f2003 was a long time
ago (nearly a decade). I think this was among the first
fixes.
There are plenty of uses for such things as public module
procedures with arguments of private type. I used to have some
and had to rework things to avoid them. The private type
argument was an optional argument only useful for calls
within the module, but the procedure was still useful outside
the module with that argument omitted. There are other
possibly useful scenarios also.
Those restrictions were a misguided attempt to achieve
things that they weren't effective at anyway.
Gotta run.
--
Richard Maine | Good judgment comes from experience;
email: my first.last at org.domain | experience comes from bad judgment.
org: nasa, domain: gov | -- Mark Twain
| |
| James Van Buskirk 2004-03-27, 12:17 am |
| "Richard Maine" <nospam@see.signature> wrote in message
news:m1znacz81j.fsf@macfortran.local...
> That strange pickiness is gone...
Awesome! Thanks.
--
write(*,*) transfer((/17.392111325966148d0,6.5794487871554595D-85, &
6.0134700243160014d-154/),(/'x'/)); end
|
|
|
|
|