The following interface appears to be standard-conforming,
interface
function test(Matrix) result(res)
real, value :: Matrix(:,:)
real :: res
end function
end interface
end
but GFortran yields the following error message:
Error: VALUE attribute conflicts with DIMENSION attribute at (1)
The GFortran’s behavior conforms with F2003 but not with the newer standards. Am I right? I just wanted to confirm here with more knowledgeable people before reporting it.
I have compiled the code with Intel Fortran oneAPI and indeed, with default options, it is accepted, but if you specify -stand:f03, it issues this warning:
value_dim.f90(7): warning #8713: Specifying a VALUE attribute for an array is an extension of Standard F2003. [MATRIX]
real, value :: Matrix(:,:)
-----------------------^
What could be a use case for an array with value attribute? In C, arrays are always passed as pointers. I thought of a struct containing an array as its only member, passed by value to a Fortran procedure.
But, in MFE 2018, sect. 19.9 “Interoperability of procedures”, one reads (emphasis is mine):
A Fortran procedure is interoperable if it has an explicit interface and is declared with the bind attribute […]
Each dummy argument must be interoperable and neither optional nor an array with the value attribute.
Indeed, the code made interoperable:
interface
function test(Matrix) result(res) bind(C)
use, intrinsic :: iso_c_binding
real(c_float), value :: Matrix(:,:)
real(c_float) :: res
end function
end interface
end
fails to compile:
>ifort -c value_array_arg_cbind.f90
value_array_arg_cbind.f90(5): error #7292: A dummy argument with the VALUE attribute cannot be an array or an array pointer. [MATRIX]
real(c_float), value :: Matrix(:,:)
------------------------------^
In Fortran a specific use of the value attribute can be that you change the value of the argument but do not pass the new value back to the caller. It would not matter if the argument is a scalar or an array, though I can imagine implementation issues if the argument is a derived type with pointer components (that is probably not allowed, but I have not checked). Whether that is very useful in practice is another matter.
Yes, Fortran 2008 revision extended some of the semantics with the VALUE attribute, a feature that was introduced starting Fortran 2003.
Fortran 2008 onward, the standard permits the VALUE attribute for an array and also for an object with a non-constant length-type parameter (check CHARACTER and parameterized derived types).
Incidentally the Fortran standard document (c.f. 10-007r1 for an unofficial copy) omitted the listing of this extension to the VALUE attribute from its Introduction section. Fortran 2018 (c.f. 18-007r1) pointed this out in section C.1 in its Appendix. A possible consequence of this is uneven support of the facility in Fortran processors as compiler developers sometimes tend to miss out on subsequent extensions to a feature when the extension is considered as minor and it is not spiked out in a readily noticeable manner in the standard document.
Arjen’s response summarizes my intentions and the use case well. Occasionally, a copy of the array has to be made inside a routine to avoid modification of an array argument of intent(in). The value attribute is a neat (perhaps only a syntactical) solution to such use cases (within Fortran, no CFI involved). Based on the responses, this appears to be a feature not yet implemented in gfortran (or better to say, implemented too restrictively).