Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
Announcements
Welcome to the Intel Community. If you get an answer you like, please mark it as an Accepted Solution to help others. Thank you!
26733 Discussions

Custom constructor initializing constant - error #6259 with IFORT 18.2

Wolf_W_
New Contributor I
168 Views

Hello,

since IFORT 18 Update 2 i get an error when i try to use custom constructors on derived type constants. In the following example it throws two errors in Line 14:
error #6259: This array or function or substring is invalid in constant expressions.   [CONSTRUCTOR3X1]
error #7715: Replacing invalid structure constructor by integer 1.   [<NULL_STRING>]

Code:

module M_MODULE
  use, intrinsic :: iso_fortran_env, only: DP => real64


  type, public :: T_VEC
    real(DP), public :: vec(1:3) = [0.0_DP,0.0_DP,0.0_DP]
  end type T_VEC

  interface T_VEC
    module procedure constructor3x1
    module procedure constructorXYZ
  end interface T_VEC

  type(T_VEC), parameter, public :: E_X = T_VEC([1.0_DP,0.0_DP,0.0_DP])
  type(T_VEC), parameter, public :: E_0 = T_VEC()

contains

  pure function constructor3x1(array) result(new_vec)
    real(DP), intent(in) :: array(3)
    type(T_VEC) :: new_vec

    new_vec%vec = array

  end function constructor3x1

  elemental function constructorXYZ(x, y, z) result(new_vec)
    real(DP), intent(in) :: x,y,z
    type(T_VEC) :: new_vec

    new_vec%vec(1) = x
    new_vec%vec(2) = y
    new_vec%vec(3) = z

  end function constructorXYZ

end module M_MODULE

This worked as intendet since Version 16 i think. I was not able to find a workaround so far, as an initialization of a variable with this constructor does not work, too.

I tried to replace line 14 with

type(T_VEC), parameter, public :: E_X = transfer([1.0_DP,0.0_DP,0.0_DP], T_VEC())

This compiles in the example, but fails in my project with an ICE. And i did not try, if it works as intendet.

Is this a compiler bug or is this usage of an user defined constructor not allowed?

 

Greetings

Wolf

0 Kudos
5 Replies
andrew_4619
Honored Contributor I
168 Views
FortranFan
Honored Contributor II
168 Views

Based on a quick glance, I think this is a problem with the Fortran standard itself i.e., from OP's need point of view.  The code in the original post is non-conforming; the standard only allows certain intrinsic procedures in a constant expression that is required in a named constant declaration.

Given what OP shows though, defined constructor is not needed, the following should work fine:

module M_MODULE

   use, intrinsic :: iso_fortran_env, only: DP => real64


   type, public :: T_VEC
      real(DP), public :: vec(1:3) = [0.0_DP,0.0_DP,0.0_DP]
   end type T_VEC

   type(T_VEC), parameter, public :: E_X = T_VEC([1.0_DP,0.0_DP,0.0_DP])
   type(T_VEC), parameter, public :: E_0 = T_VEC()

end module M_MODULE

 

The case mentioned by Andrew is different; the named constant in there uses the default constructor which is ok; the defined constructor interface with one dummy argument is different from what is used in the named constant, so it doesn't come into play other than perhaps 'confuse' the compiler.

Steve_Lionel
Black Belt Retired Employee
168 Views

I agree with FortranFan here - user generic constructors are not allowed in constant expressions.

However, that your substitution using TRANSFER got an ICE is definitely a compiler bug, and you should report it to Intel.

Wolf_W_
New Contributor I
168 Views

Thanks Steve and FortranFan for the clarification on the standard conformity.

I didn't realize that i can leave out the "standard" constructor from the interface. It works now with just the special constructors in the interface.

  interface T_VEC
!    module procedure constructor3x1
    module procedure constructorXYZ
  end interface T_VEC

I will try to post an example for ICE, as soon as i can pin it down.
 

Steve_Lionel
Black Belt Retired Employee
168 Views

Better to submit the ICE at https://supporttickets.intel.com/?lang=en-US , since you'll be asked to do so anyway.

Reply