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

Error: VALUE attribute conflicts with DIMENSION attribute

120 views
Skip to first unread message

Darrell Reich

unread,
May 21, 2023, 8:46:19 PM5/21/23
to
Can anyone share an alternative syntax for the pass by value assumed shape array dimension below? Porting from Intel to Cygwin gfortran version 11.3.0
What is the current status of the gfortran standard compliance?
Are the results of the test suite posted?

Downloaded gfortran test suite. Found error message--see gfortran.dg-master\assumed_rank_11.f90
Does this test tell DejaGnu that the test passes if the compiler error occurs?

Here is my Minimal Reproducible Example (MRE). I found an alternative syntax for the import only command. I need to find a workaround to the assumed shape pass by value dimension in our ISO_C_BINDING code.

! Compare gfortran, flang, ifort classic, & Intel LLVM compilers
! Fortran 2008 extended Fortran 2003 ISO_C_BINDING standard
module foo
use, intrinsic :: ISO_C_BINDING, only : C_FLOAT

interface cbrt ! call C cube root
function cbrt(x) bind(C, name="cbrtf")
!import, only : C_FLOAT ! intel
import C_FLOAT ! gfortran
implicit none
real(KIND=C_FLOAT) :: cbrt
real(KIND=C_FLOAT), value :: x
end function cbrt
end interface
contains
subroutine val1(x)
integer, dimension(:), value :: x ! Error: VALUE attribute conflicts with DIMENSION attribute
end subroutine val1
end module foo

gah4

unread,
May 21, 2023, 9:11:47 PM5/21/23
to
On Sunday, May 21, 2023 at 5:46:19 PM UTC-7, Darrell Reich wrote:
> Can anyone share an alternative syntax for the pass by value assumed shape array dimension below?
> Porting from Intel to Cygwin gfortran version 11.3.0

I presume you checked the standard to see if it is supposed to work.

In C, you can't pass arrays by value, but pointers to arrays are passed.
You can pass a struct with an array in it, but then the array has to be fixed dimension.
And you can pass a struct with a pointer to an array.

eugene_...@yahoo.com

unread,
May 22, 2023, 8:05:50 AM5/22/23
to
ChatGPT prompt: Write a Fortran BIND_C function that accepts C array of float

ChagGTP answer:

You can define a Fortran subroutine that uses the `bind(C)` attribute to make it callable from C. This subroutine could accept a C-style array of floats. Here's an example of such a function:

```fortran
subroutine process_c_float_array(arr, size) bind(C)
use iso_c_binding, only: c_float, c_int
implicit none
integer(c_int), value :: size
real(c_float), dimension(*), intent(inout) :: arr
! here you can manipulate the array `arr`
! for demonstration purposes, let's just multiply every element by 2
arr = arr * 2.0_c_float
end subroutine process_c_float_array
```

This Fortran subroutine `process_c_float_array` accepts a one-dimensional array of `c_float` values (which correspond to `float` values in C) and its size, and modifies the array.

Note that the `value` attribute is used for `size` to ensure that it is passed by value, following the C convention, instead of by reference, which is the Fortran default. The `intent(inout)` attribute is used for `arr` to indicate that the subroutine can both read from and modify this array.

You could call this Fortran subroutine from a C program like this:

```c
extern void process_c_float_array(float* arr, int size);
```

Remember that `c_float` and `c_int` are Fortran types that are guaranteed to have the same size and representation as the C types `float` and `int`, respectively. This is important to ensure compatibility between Fortran and C.

Make sure your Fortran compiler supports the Fortran 2003 standard or later, which introduced the C interoperability features used here. Also, depending on the specifics of your Fortran and C compilers, you might need to apply compiler-specific options or use certain conventions for the names of the Fortran procedures when calling them from C.

Thomas Koenig

unread,
May 23, 2023, 4:20:37 PM5/23/23
to
Darrell Reich <dre...@yahoo.com> schrieb:
> Can anyone share an alternative syntax for the pass by value assumed shape array dimension below? Porting from Intel to Cygwin gfortran version 11.3.0
> What is the current status of the gfortran standard compliance?
> Are the results of the test suite posted?
>
> Downloaded gfortran test suite. Found error message--see gfortran.dg-master\assumed_rank_11.f90
> Does this test tell DejaGnu that the test passes if the compiler error occurs?

The test case is about assumed rank, which is a strange beast.

Regarding arrays passed by value: Fortran 2003 has a constraint:

C527 (R501) If the VALUE attribute is specified, the PARAMETER,
EXTERNAL, POINTER, ALLOCATABLE, DIMENSION, VOLATILE, INTENT(INOUT),
or INTENT(OUT) attribute shall not be specified.

In contrast, F2008 has

(C558) An entity with the VALUE attribute shall not have the
ALLOCATABLE, INTENT (INOUT), INTENT (OUT), POINTER, or VOLATILE
attributes.

so this rule was relaxed for Fortran 2008.

gfortran simply has not yet implemented this particular feature.


> Here is my Minimal Reproducible Example (MRE). I found an alternative syntax for the import only command. I need to find a workaround to the assumed shape pass by value dimension in our ISO_C_BINDING code.

>
> ! Compare gfortran, flang, ifort classic, & Intel LLVM compilers
> ! Fortran 2008 extended Fortran 2003 ISO_C_BINDING standard
> module foo
> use, intrinsic :: ISO_C_BINDING, only : C_FLOAT
>
> interface cbrt ! call C cube root
> function cbrt(x) bind(C, name="cbrtf")
> !import, only : C_FLOAT ! intel
> import C_FLOAT ! gfortran
> implicit none
> real(KIND=C_FLOAT) :: cbrt
> real(KIND=C_FLOAT), value :: x
> end function cbrt
> end interface
> contains
> subroutine val1(x)
> integer, dimension(:), value :: x ! Error: VALUE attribute conflicts with DIMENSION attribute
> end subroutine val1
> end module foo

VALUE for arrays can be a bit tricky, the compiler would
have to copy the arry on procedure entry.

If your subroutine was called with an array bar, like

call bal1(bar)

the complier would, in effect, do

block
integer, dimension(size(bar)) :: bar_tmp
bar_tmp = bar
call val1(bar_tmp)
end block

val could then change the contents of its arguments without
affecting bar in the calling subprogram (which is what VALUE
is about).

Is that actually what you want?

Steve Lionel

unread,
May 24, 2023, 12:27:49 PM5/24/23
to
On 5/23/2023 4:20 PM, Thomas Koenig wrote:

> Regarding arrays passed by value: Fortran 2003 has a constraint:
>
> C527 (R501) If the VALUE attribute is specified, the PARAMETER,
> EXTERNAL, POINTER, ALLOCATABLE, DIMENSION, VOLATILE, INTENT(INOUT),
> or INTENT(OUT) attribute shall not be specified.
>
> In contrast, F2008 has
>
> (C558) An entity with the VALUE attribute shall not have the
> ALLOCATABLE, INTENT (INOUT), INTENT (OUT), POINTER, or VOLATILE
> attributes.
>
> so this rule was relaxed for Fortran 2008.
>

It is worth noting that VALUE has a very different meaning depending on
whether the procedure being called has BIND(C) or not. Without BIND(C),
a writable temporary copy is passed using the mechanism the particular
compiler would use without VALUE.

If the procedure does have BIND(C), then VALUE means "pass by value" as
in C. In this case, arrays are not permitted. As is often the case, the
words in the standard for this are not immediately obvious. In F2018,
18.3.6 says:

> (4) any scalar dummy argument with the VALUE attribute is interoperable with the corresponding formal parameter of the prototype,
> (5) any dummy argument without the VALUE attribute corresponds to a formal parameter of the prototype that is of a pointer type, and...

Note that (4) is restricted to "scalar dummy argument". Since the
standard does not describe the meaning of an array dummy argument with
VALUE, such a combination is not allowed by the standard.

The example in this case is not using VALUE for an argument in a
procedure with BIND(C), so that is allowed as of F2008 as noted.

--
Steve Lionel
ISO/IEC JTC1/SC22/WG5 (Fortran) Convenor
Retired Intel Fortran developer/support
Email: firstname at firstnamelastname dot com
Twitter: @DoctorFortran
LinkedIn: https://www.linkedin.com/in/stevelionel
Blog: https://stevelionel.com/drfortran
WG5: https://wg5-fortran.org

gah4

unread,
May 24, 2023, 1:02:55 PM5/24/23
to
On Wednesday, May 24, 2023 at 9:27:49 AM UTC-7, Steve Lionel wrote:

(snip)

> It is worth noting that VALUE has a very different meaning depending on
> whether the procedure being called has BIND(C) or not. Without BIND(C),
> a writable temporary copy is passed using the mechanism the particular
> compiler would use without VALUE.

> If the procedure does have BIND(C), then VALUE means "pass by value" as
> in C. In this case, arrays are not permitted. As is often the case, the
> words in the standard for this are not immediately obvious.

C does allow passing arrays inside a struct by value.

I presume Fortran knows how to do that?


Steve Lionel

unread,
May 24, 2023, 1:35:17 PM5/24/23
to
On 5/24/2023 1:02 PM, gah4 wrote:
> C does allow passing arrays inside a struct by value.
>
> I presume Fortran knows how to do that?

That is allowed.
0 new messages