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

New Fortran compiler has so many changes

Zhanghong_T_
Novice
1,416 Views
Dear administrator, I have a Fortran code which worked for many years by Intel Fortran 2011-2020. However, it doesn't work for latest Fortran compiler in Intel OneAPI, hundreds of errors appears. For example, for the following code: subroutine writeerrormsg(filename,msg) implicit none character*(*)::filename,msg call writestring(c_loc(trim(filename)//''C),c_loc(trim(msg)//''C)) end subroutine The following error displayed: error #9022: The argument to C_LOC must be a variable with the POINTER or TARGET attribute.  Similar errors appear in the following code: ...c_loc('+')... ...c_loc(array)...     !      real*8::array(3) I want to know is there any compiler settings or 'quick method' to let the latest compiler to be able to compile my Fortran code. Thanks, Tang Laoya
2 Replies
Steve_Lionel
Honored Contributor III
1,380 Views

The compiler is enforcing a rule in the standard - your code is incorrect.  The standard says:

"X shall have either the POINTER or TARGET attribute. It shall not be a coindexed object. It shall be a variable with interoperable type and kind type parameters, an assumed-type variable, or a nonpolymorphic variable that has no length type parameter. If it is allocatable, it shall be allocated. If it is a pointer, it shall be associated. If it is an array, it shall be contiguous and have nonzero size. It shall not be a zero-length string."

You're not allowed to take C_LOC of an expression. What does routine writestring look like? I'm puzzled that you find the need to use C_LOC in this context.

jimdempseyatthecove
Honored Contributor III
1,380 Views

Laoya,

 

When posting code samples to this forum click on the tool bar "..." button for additional options. In the additional options then click on the "</>" button. This will open an edit box that contans a pull-down control which contains formatting options. One of which is for Fortran. Using this results in your post becoming:

subroutine writeerrormsg(filename,msg)
 implicit none
 character*(*)::filename,msg
 call writestring(c_loc(trim(filename)//''C),c_loc(trim(msg)//''C))
end subroutine


Laoya>>The following error displayed (using "Plain text" formatting):

error #9022: The argument to C_LOC must be a variable with the POINTER or TARGET attribute.


Similar errors appear in the following code:

...
c_loc('+')
...
c_loc(array)
...
! real*8::array(3) 

 

 

Laoya>>I want to know is there any compiler settings or 'quick method' to let the latest compiler to be able to compile my Fortran code.

 

Jim Dempsey>>

To correct the error, using the compiler reference, enter in search "target attribute" as this is what the error message is referring to:

This results in  Search (intel.com)

Click on the top link "TARGET Statement"

This will inform you as to how to attribute variables with the TARGET attribute.

subroutine writeerrormsg(filename,msg)
 implicit none
 character*(*), target :: filename,msg
 call writestring(c_loc(trim(filename)//''C),c_loc(trim(msg)//''C))
end subroutine

 

Regarding c_loc:

c_loc is an intrinsic function of the iso_c_binding (as opposed to the non-standard LOC(x) intrinsic. Searching the compiler reference for c_loc you find:

 

C_LOC
Intrinsic Module Inquiry function (Generic): Returns the C address of an argument.
Module
USE, INTRINSIC :: ISO_C_BINDING
Syntax
result = C_LOC(x)
x
(Input) Is a non-coindexed variable that has the TARGET attribute. It must have interoperable type and type parameters, and it must be a non-polymorphic variable with no length type parameters, or an assumed-type variable.
If it is an array, it must be contiguous with non-zero size. It cannot be a zero-length string. If it is a pointer, it must be associated. If it has the ALLOCATABLE attribute, it must be allocated.
Results
The result is a scalar of derived type C_PTR. The result value represents the C address of the argument.
The result is a value that can be used as an actual CPTR argument in a call to procedure C_F_POINTER where fptr has attributes that allow the pointer assignment fptr=>x. Such a call to C_F_POINTER has the effect of the pointer assignment fptr=>x.
If x is a scalar, the result is determined as if C_PTR were a derived type containing a scalar pointer component PX of the type and type parameters of x and the pointer assignment CPTR%PX=>x were executed.
If x is an array, the result is determined as if C_PTR were a derived type containing a scalar pointer component PX of the type and type parameters of x and the pointer assignment CPTR%PX to the first element of x were executed.

Therefore, the correct coding is:

 

subroutine writeerrormsg(filename,msg)
 use, intrinsic :: iso_c_binding
 implicit none
 character*(*), target :: filename,msg
 call writestring(c_loc(trim(filename)//''C),c_loc(trim(msg)//''C))
end subroutine

*** however, this may (should) require an interface for writestring (which appears to be a C/C++ subroutine/void function). 

Search for BIND(C), and INTERFACE for aid in declaring your interfaces. Hint, place your interface declarations into a module that you can USE. Fortran generates UPPERCASE symbols by default. Without a properly written interface, the linking symbol may be either WRITESTRING or _WRITESTRING (depending on build options).

 

 Jim Dempsey

Reply