2

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).

2
  • I think it has to be a function type(bicomplex) function dble_assign_bicplx(qleft, xright) Commented Aug 25, 2014 at 23:41
  • 1
    If defined assignment was specified by a function, then how would you control the assignment of the function result to the thing on the left hand side of the assignment? Commented Aug 26, 2014 at 0:10

2 Answers 2

2

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.

Sign up to request clarification or add additional context in comments.

Comments

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.

3 Comments

Thanks! So there is NO way to create a bicomplex named constant without using the bicomplex() operator? That's inconvenient...
This answer has gone all a bit messy and wandering: I'll leave my thoughts and welcome comment.
francescalus had it right the first time. The = in initialization is not assignment, it is the syntax introducing the initialization value. In this case, bicomplex() is a structure constructor and indeed there is no other way in this context to create a value of that type.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.