Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.

Unrecognized intrinsic functions

Aaron_S_1
Beginner
3,285 Views

I've encountered strange issues in the past when trying to compile source that has an intrinsic function. I get "error#6410: This name has not been declared as an array or a function. [MIN]." when trying to compile the following:

subroutine find_min_range( min_range, km_to_m, pos_a, pos_b)

   real(8), intent(in out) :: min_range 
   real(8), intent(in    ) :: km_to_m
   real(8), intent(in    ) :: pos_a(3)
   real(8), intent(in    ) :: pos_b(3)

   real(8) :: a_to_b(3), range

   a_to_b    = pos_b - pos_a
   range     = norm2( a_to_b )
   range     = range * km_to_m
   min_range = min( range, min_range)

   return

end subroutine find_min_range

I've seen this same problem before with the functions size, and max. In those cases I had to pass in the size of the array and use an if statement to accomplish what "max()" does. Am I doing something wrong? I've checked through the entire solution to be sure I haven't redefined the min function, and min is not a variable. The source file compiled without any issue, I added a really simple if statement in the same file but another routine, went to recompile it, and now this source file will no longer compile. This routine also hasn't been changed in over 4 years. Unfortunately I cannot post any more code than this. Thanks for any advice in advance.

0 Kudos
22 Replies
Aaron_S_1
Beginner
3,029 Views

I should probably add this:

Intel(R) Visual Fortran Composer XE 2013 SP1 Update 3 Integration for Microsoft Visual Studio* 2010, 14.0.0092.2010, Copyright (C) 2002-2014 Intel Corporation
* Other names and brands may be claimed as the property of others.

0 Kudos
mecej4
Honored Contributor III
3,029 Views

Your sample code does not produce any error/warning messages when run with the 14.0.4.237 compiler, but the syntax coloring that the forum software applies is, by itself, pointing out a source of trouble: the variable 'range' hides the intrinsic function of the same name. Something similar may have happened in your troublesome code but, without seeing the code that actually causes the compiler to complain, one cannot be sure.

Note that 'norm2' is of type default integer in your code, and probably not intended to be of that type. Try adding IMPLICIT NONE to your subprograms and modules.

0 Kudos
Aaron_S_1
Beginner
3,030 Views

I wrote this subroutine from memory because the code is not located on a machine with internet access. I verified that the variable isn't actually called range, and that the source file which this code appears in contains implicit none. I couldn't figure out how to edit my original post, so I've updated the code here. Since I made this post I cleaned the project and restarted the computer and everything compiles fine again.

subroutine find_min_range( min_range, km_to_m, pos_a, pos_b)

   real(8), intent(in out) :: min_range 
   real(8), intent(in    ) :: km_to_m
   real(8), intent(in    ) :: pos_a(3)
   real(8), intent(in    ) :: pos_b(3)

   real(8) :: a_to_b(3), range_km, range_m

   a_to_b    = pos_b - pos_a
   range_km  = norm2( a_to_b )
   range_m   = range_km * km_to_m
   min_range = min( range_m, min_range)

   return

end subroutine find_min_range

 

0 Kudos
mecej4
Honored Contributor III
3,030 Views

OK, but your updated code still has 'norm2' as a function with, apparently, the wrong type: integer.

0 Kudos
JVanB
Valued Contributor II
3,030 Views

NORM2 is an f2008 intrinsic :)

 

0 Kudos
mecej4
Honored Contributor III
3,030 Views

Repeat Offender wrote:

NORM2 is an f2008 intrinsic :)

And recognized by IFort. Thanks for the tip.

0 Kudos
jimdempseyatthecove
Honored Contributor III
3,030 Views

Steve (if you are reading this)

RE: NORM2 is an f2008 intrinsic :)

Considering the addition of new intrinsic functions and the experience of Aaron, it might be worthy to have a diagnostic option that warns

a) when an implicit variable name conflicts with an intrinsic function
b) when an explicit variable name conflicts with an intrinsic function
(different message for instance)

Jim Dempsey

0 Kudos
Steven_L_Intel1
Employee
3,030 Views

Jim, I am still puzzled as to what Aaron was seeing regarding MIN, as that isn't reproducible. Otherwise I'm not seeing the benefit of such an option and don't see how it would have helped here. What am I missing?

0 Kudos
Aaron_S_1
Beginner
3,030 Views

I'm encountering the same error again this morning, but my colleague can compile the code without any problems. I think I will reinstall my compiler at this point. Thanks for the help.

 

0 Kudos
Steven_L_Intel1
Employee
3,030 Views

I doubt a reinstall will help. Try doing a Build > Clean first and then a rebuild. If you continue to have trouble, please ZIP up your project and either attach it here (do a Build > Clean before zipping) or submit it to Intel Premier Support and we'll see if we can help.

0 Kudos
JVanB
Valued Contributor II
3,030 Views

ifort already has some tools to show the programmer that it is recognizing an f2008 intrinsic.

D:\quote4>ifort /nologo /warn:declarations /c quote4.f90

D:\quote4>ifort /nologo /stand:f03 /c quote4.f90
quote4.f90(11): warning #7416: Fortran 2003 does not allow this intrinsic proced
ure.   [NORM2]
   range_km  = norm2( a_to_b )
---------------^

The first was a negative result by forcing IMPLICIT NONE, and the second was a positive result by asking the compiler to warn about f2008 intrinsics. Sorry I didn't have time to post at length about this previously.

 

0 Kudos
jimdempseyatthecove
Honored Contributor III
3,030 Views

Steve,

The purpose of the suggested option was to resolve the inverse of what Repeat Offender is posting. Consider the case where the user has 40 year old code. The code happens to have been compiled without IMPLICIT NONE. Add to this the code having its own NORM2 function (ignoring for the moment that norm2 is implicitly integer and range_km is implicitly real). The effect of compiling as F2008 (which may become default at some point), would be to replace the program's NORM2 with the intrinsic NORM2, thus introducing an error in the program. This error may be very hard to find without the aid of a diagnostic.

Jim Dempsey

0 Kudos
mecej4
Honored Contributor III
3,030 Views

I would like to second Jim's suggestion. I have, on several occasions, run into problems with old F77 code with variables 'sum', 'min' and 'max'. Conversion to F95 often involves replacing 2- or 3-line DO loops with the intrinsic SUM applied to arrays, which then clashes with the local variable SUM, making it necessary to change the variable name to something else, such as SUM0, and so on.

The PSRV v77to90 converter gives a warning when applied to such old codes:

 Warning, line 2093:
    Input contains reserved word -- may inhibit translation (SUM)

Something similar, warning about local variables making intrinsics inaccessible, available as an option in IFort, would be welcome.

0 Kudos
John4
Valued Contributor I
3,030 Views

jimdempseyatthecove wrote:

The effect of compiling as F2008 (which may become default at some point), would be to replace the program's NORM2 with the intrinsic NORM2, thus introducing an error in the program.

IIRC, in Fortran, user-defined procedures have precedence over intrinsics with the same name, unless you explicitly state that the intrinsic one should be used, so no error would be introduced in a program like that.

In the following code, with "-warn all", I get no warning at all, but my version of norm2 is used over the intrinsic one:

module mod1
contains
    function norm2(x, y)
        real :: norm2, x, y
        norm2 = sqrt(x**3 + y**3)
    end function
end module mod1
use mod1
print *, norm2(3., 4.)
end


 

gfortran, with the "-Wall" option, throws a "would-be-nice-to-have-in-ifort" warning: 'norm2' declared at (1) may shadow the intrinsic of the same name. In order to call the intrinsic, explicit INTRINSIC declarations may be required.


 

0 Kudos
jimdempseyatthecove
Honored Contributor III
3,030 Views

John,

You are missing the point. The problem is the F77 (or earlier) program won't have modules ... and won't declare a function interfaces. Both/either are required to define a function that supersedes an intrinsic, but neither of which exists in the old code (now with the intrinsic function name conflicting with their code).

Mecej illustrated an example.

Jim Dempsey

0 Kudos
John4
Valued Contributor I
3,030 Views

I see your point! But stating that the procedure being invoked is EXTERNAL, is all that's required, for example:

function norm2(x, y)
    real norm2, x, y
    norm2 = sqrt(x**3 + y**3)
end function

real norm2
external norm2
print *, norm2(3., 4.)
end

And again, gfortran shows the following warning: 'norm2' declared at (1) is also the name of an intrinsic. It can only be called via an explicit interface or if declared EXTERNAL.

I've seen old code with extremely detailed preambles (i.e., documentation), but that include a few, if any, EXTERNAL statements... maybe only for the procedures the particular compiler/linker couldn't resolve? That's like using :: only after the compiler throws an error.

It seems to me that in Fortran 66/77, things always happened in mysterious ways.



 

0 Kudos
Steven_L_Intel1
Employee
3,030 Views

How is the compiler supposed to know that you didn't want the intrinsic? The way the language works, as John suggests, EXTERNAL is how you tell the compiler a name is an external function and not intrinsic in F77. If there is no EXTERNAL (or other function declaration), and the arguments match, the intrinsic will be used. If the arguments don't match, the compiler will tell you so.

0 Kudos
jimdempseyatthecove
Honored Contributor III
3,030 Views

Steve,

>>How is the compiler supposed to know that you didn't want the intrinsic?

Earlier versions of FORTRAN implicitly assumed X(something) had external linkage if it weren't declared. Ergo, one wouldn't know where or what to mark as EXTERNAL. Having a diagnostic option would quickly point out these locations. I suppose in this case one could use /warn:interfaces to locate the missing external... *** provided the X(something) didn't match the interface of an intrinsic that wasn't available when the program was originally written.

Jim Dempsey

0 Kudos
Steven_L_Intel1
Employee
3,030 Views

An idea that has been kicking around is to have an optional warning for a call to a procedure with an implicit interface, to help those who don't want to use the past and present feature of implicit interface you mention. But I don't know how this would help if you used the name of an intrinsic when you wanted your own routine instead. There was a proposal to add syntax for this, along the lines of IMPLICIT NONE, but my recollection was that it did not pass.

0 Kudos
jimdempseyatthecove
Honored Contributor III
2,530 Views

>>But I don't know how this would help if you used the name of an intrinsic when you wanted your own routine instead.

Isn't this what an INTERFACE block is supposed to do?

Jim Dempsey

0 Kudos
Reply