Fortran derived types: Overloaded assignment operator not working with 'PARAMETER' attribute

两盒软妹~` 提交于 2019-12-19 10:26:37

问题


I am using a derived type (bicomplex), and an overload of the assignment operator (=), so that one can assign a real*8 to bicomplex. A MWE of the bicplx module follows:

MODULE bicplx

  type bicomplex
    COMPLEX*16 :: a
    COMPLEX*16 :: b
  end type

  interface assignment(=)
    module procedure dble_assign_bicplx
  end interface

contains

  subroutine dble_assign_bicplx(qleft, xright) 
    implicit none         
    type(bicomplex), intent(out) :: qleft
    double precision, intent(in) :: xright

    qleft%a = xright
    qleft%b = 0.0d0          
    return
  end subroutine dble_assign_bicplx

end MODULE

The assignment of real to complex is handled intrinsically by Fortran. This method works well when used on "typical" bicomplex variables, but breaks when I want to assign a real*8 to a bicomplex which has the PARAMETER attribute:

TYPE(bicomplex) :: test1
test1 = 1.d0

works perfectly, but:

TYPE(bicomplex), parameter :: test1 = 1.d0

does not compile and gives 2 errors: Error: Incompatible derived type in PARAMETER at (1), and Error: Can't convert REAL(8) to TYPE(bicomplex) at (1). However,

TYPE(bicomplex), parameter :: test1 = bicomplex(1.d0, 0.d0)

works perfectly.

Is there something I am missing, or is it part of the standards that a parameter can not be assigned by using an overloaded assignment operator? Ideally, I'd like to solve this using F90/F95 (and not 2003 or 2008).


回答1:


A "parameter" is a named constant. The rules of the language require that the value of a named constant can be determined at "compile time" - i.e. before the program is executed. That means that the expression used to give a named constant its value need to be able to be determined at compile time. The language terminology for this in recent standards is "constant expression", in earlier standards it was also called "initialization expression" (something that could be used as an initializer - before program execution).

Defined assignment is an executable action - when run the program executes the statements in the procedure that sits behind the defined assignment. This is not something that can generally be done at compile time.

As you have discovered, you can use structure constructors where the component initializers are constant expressions to initialize derived type named constants.




回答2:


My reading of the standard is that one cannot use a defined operator here. My thinking is that this is because the operator is for defined assignment where for a named constant initialization is used (see R503 and C507 of Fortran 2008, in section 5.2.1).

In Fortran 2008 section 5.2.3, regarding initialization:

If initialization is = constant-expr, the variable is initially defined with the value specified by the constant-expr; if necessary, the value is converted according to the rules of intrinsic assignment

There may be some ambiguity in that paragraph (not shown) as it starts by referring to entities without the parameter attribute. So, looking on, in section 5.3.13 for the parameter attribute:

The entity has the value specified by its constant-expr, converted, if necessary, to the type, type parameters and shape of the entity.

However, section 5.4.11 (for the parameter statement) perhaps reinforces that this conversion is by intrinsic assignment:

The value of each named constant is that specified by the corresponding constant expression; if necessary, the value is converted according to the rules of intrinsic assignment

For the first named constant case there is no intrinsic assignment from the intrinsic type to the derived type. In the second case, using the constructor for the derived type, intrinsic assignment is indeed being used.



来源:https://stackoverflow.com/questions/25495549/fortran-derived-types-overloaded-assignment-operator-not-working-with-paramete

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!