Code or Compiler Error?

I am attempting to compile the following on intel MacOS 10.14.6 with what I think is the latest version of the ifort intel compiler.

$ cat cte.f90
use iso_fortran_env, only: compiler_options, compiler_version
character(*), parameter :: compiled_by = compiler_version()
character(*), parameter :: compiled_with = compiler_options()

$ ifort --version
ifort (IFORT) 2021.6.0 20220226
Copyright (C) 1985-2022 Intel Corporation.  All rights reserved.

$ ifort -c cte.f90
cte.f90(2): error #6263: This intrinsic function is invalid in constant expressions.   [COMPILER_VERSION]
character(*), parameter :: compiled_by = compiler_version()
cte.f90(3): error #6263: This intrinsic function is invalid in constant expressions.   [COMPILER_OPTIONS]
character(*), parameter :: compiled_with = compiler_options()
compilation aborted for cte.f90 (code 1)

This is almost identical to an example in Modern Fortran Explained. These intrinsic functions were introduced in f2008, so I’m not pushing any limits regarding new features. I’m wondering, is this a problem with my code, or with the compiler, or what?

Perhaps it is related to this bug?

Edit: With respect to the inquiry re: a bug in Intel Fortran in the original post, please see this comment post further below in this thread.

The operative word is “almost”: you have the answer in the error message, “This intrinsic function is invalid in constant expressions.” The standard is rather limiting when it comes to what is allows in constant expressions and the standard defined functions from the intrinsic module ISO_FORTRAN_ENV are not among the permitted ones.

You can try this out first where the restrictions of constant expressions with defining named constants do not apply:

   use iso_fortran_env, only: compiler_version
   character(len=:), allocatable :: compiled_by
   compiled_by = compiler_version()
   print *, compiled_by

C:\temp>ifort /standard-semantics p.f90
Intel(R) Fortran Intel(R) 64 Compiler Classic for applications running on Intel(R) 64, Version 2021.6.0 Build 20220226_000000
Copyright (C) 1985-2022 Intel Corporation. All rights reserved.

Microsoft (R) Incremental Linker Version 14.30.30706.0
Copyright (C) Microsoft Corporation. All rights reserved.


Intel(R) Fortran Intel(R) 64 Compiler Classic for applications running on Intel
(R) 64, Version 2021.6.0 Build 20220226_000000

1 Like

The only difference in my code and the MFE code is that theirs is in a module. I just put the same statements into a four line main program when I posted it here. MFE says “These functions may be used in initialization expressions, for example…” and then they show their code.

This sentence is in both the f2008 and the f2018 version of MFE. So if it was a mistake, they had 10 years to correct it and they failed to change it.

Can you tell me where in the f2018 standard to look for the list of included/excluded intrinsic functions?

It looks like that bug was fixed in the version of the compiler that I’m using. If it is a bug in the compiler, and not my code, then perhaps they are related bugs.

On a related question, in that example the trim() function was used. I’ve been assuming that the return values for those two functions are already in their trimmed form. At least for the versions of gfortran that I’ve tried where this code works, that has been the case. trim() is easy enough to add, but is it necessary? Are there any known compilers that do not returned trimmed values for those two intrinsic functions?

As I read the standard further, I’m now unsure.

My take earlier was that the standard states, “The types and procedures defined in standard intrinsic modules are not themselves intrinsic.” And thus compiler_version and compiler_option functions are not themselves intrinsic. Then in the section on constant expressions, the standard permits all transformational functions that are “standard intrinsic functions” in constant expressions. But it fails to spike out compiler_version and compiler_option functions as being allowed, so I had felt Intel Fortran was right to issue the diagnostic it did since anything that is not listed as allowed is by definition disallowed per the standard when it comes to constant expressions.

But since OP mentions the example in MFE, I am thinking there might be another “out” for these two functions to appear in constant expressions that Intel Fortran and I have not discovered yet. This is what I will try to check when I have a bit more time.

1 Like

The standard says the length of the returned values are “processor dependent” so the trim() seems prudent even if all the current implementations return it trimmed (not that I know if they do or not).

At least two compilers replace the function call with a fixed string value, which would avoid any problem with using it for initialization:

    .ident  "GCC: (Ubuntu 10.3.0-1ubuntu1~20.04) 10.3.0"

They might do that and skip generating the error. I sure thought it was not allowed as a parameter value.

Gfortran compiles the code correctly. However, I don’t know if that is an extension or, as MFE states, if that is consistent with f2008+.

The code also compiles with nagfor:
$ nagfor -c cte.f90
NAG Fortran Compiler Release 7.1(Hanzomon) Build 7109
Warning: cte.f90, line 2: Unused PARAMETER COMPILED_BY
Warning: cte.f90, line 3: Unused PARAMETER COMPILED_WITH
[NAG Fortran Compiler normal termination, 2 warnings]

Confirmed this is a bug in Intel Fortran. A support request has been filed with their software team.

The standard states in the section on Specification Expression, “A specification inquiry is a reference to … the COMPILER_VERSION or COMPILER_OPTIONS function from the intrinsic module ISO_FORTRAN_ENV (,”

The use of a specification inquiry with constant expression arguments are allowed in a constant expression, among other things. There are no parameters to the compiler_version and compiler_options functions, so they are covered.

Thus the use of compiler_version and compiler_options in the definition of a named constant is permitted and Intel Fortran compiler is incorrect in issuing the error diagnostic.