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

Can a named-constant in a complex-literal-constant have rank > 0?

250 views
Skip to first unread message

Peter Klausler US

unread,
Nov 2, 2022, 3:32:26 PM11/2/22
to
C718 requires that a named-constant that is used as the real-part or imag-part of a complex-literal-constant have a real or integer type, but it doesn't say anything about its rank. Some compilers allow an array-valued named constant to appear, others do not. For example:

real, parameter :: arr2(2) = [1., 2.]
print *, (arr2, 3.)

Is there language anywhere else in the standard that requires such a named-constant to be scalar, or that implies such a constraint because a complex-literal-constant is assumed to be scalar? I can't find anything definitive one way or another.

jfh

unread,
Nov 2, 2022, 4:32:39 PM11/2/22
to
It seems that it can be an array but not a coarray. In the F2018 standard, R719 and R720 say the real-part and imag-part
may be named constants, and 8.5.13 allows named constants that are arrays but not coarrays.

jfh

unread,
Nov 2, 2022, 4:55:33 PM11/2/22
to
But the gfortran developers know Fortran better than I do and gfortran gives the error message
3 | print *, (arr2, 3.)
| 1
Error: Scalar PARAMETER required in complex constant at (1)

Ifort compiles and runs Klausler's program but prints the wrong answer:
(0.0000000E+00,3.000000)

Does any compiler print the hoped-for (1.000000,3.000000) and (2.000000,3.000000) ?

Peter Klausler US

unread,
Nov 2, 2022, 6:19:55 PM11/2/22
to
On Wednesday, November 2, 2022 at 1:55:33 PM UTC-7, jfh wrote:
> Does any compiler print the hoped-for (1.000000,3.000000) and (2.000000,3.000000) ?

f18 prints " (1.,3.) (2.,3.)".

FortranFan

unread,
Nov 2, 2022, 7:57:38 PM11/2/22
to
On Wednesday, November 2, 2022 at 4:55:33 PM UTC-4, jfh wrote:

> ..
> Does any compiler print the hoped-for (1.000000,3.000000) and (2.000000,3.000000) ?

Rather than the "hoped for", chances are high the Fortran committee will think the standard needs a quick fix here.

That is, the equivalent of R719 and R720 in the revised document be updated to state something like "scalar named-constant" instead of leaving it as "named-constant." Which will be welcome for gfortran and any other compiler that issues a similar compile-time error.

OP can directly seek clarification on this at the J3 Fortran mailing list. Or have a colleague at Nvidia do so.

Steven G. Kargl

unread,
Nov 2, 2022, 8:14:58 PM11/2/22
to
On Wed, 02 Nov 2022 13:55:31 -0700, jfh wrote:

> On Thursday, November 3, 2022 at 9:32:39 AM UTC+13, jfh wrote:
>> On Thursday, November 3, 2022 at 8:32:26 AM UTC+13, Peter Klausler US wrote:
>> > C718 requires that a named-constant that is used as the real-part or imag-part of a complex-literal-constant have a real or integer type, but it doesn't say anything about its rank. Some compilers allow an array-valued named constant to appear, others do not. For example:
>> >
>> > real, parameter :: arr2(2) = [1., 2.]
>> > print *, (arr2, 3.)
>> >
>> > Is there language anywhere else in the standard that requires such a named-constant to be scalar, or that implies such a constraint because a complex-literal-constant is assumed to be scalar? I can't find anything definitive one way or another.
>> It seems that it can be an array but not a coarray. In the F2018 standard, R719 and R720 say the real-part and imag-part
>> may be named constants, and 8.5.13 allows named constants that are arrays but not coarrays.
>
> But the gfortran developers know Fortran better than I do and gfortran gives the error message
> 3 | print *, (arr2, 3.)
> | 1
> Error: Scalar PARAMETER required in complex constant at (1)

gfortran started life as Fortran 95 compilers. Named-constants
were not permitted in a complex literal-constant. The above
error could be hold over from days past.

I was going to argument that one might be imposing some rule
for cmplx(arr2,3.) to the above, but there doesn't appear to
a rule that the real and imaginary parts are conformable.

It seems Peter has stumbled on an oversight.

--
steve

Steven G. Kargl

unread,
Nov 2, 2022, 8:17:37 PM11/2/22
to
What happens if you do

program foo
real, parameter :: a(2) = [1,2], b(3) = [1,2,3]
print *, (a,b)
end program foo

gfortran gives the same 'Scalar PARAMETER ...' error.
In your case, arr2 and 3. are conformable.

--
steve

Peter Klausler US

unread,
Nov 2, 2022, 8:20:24 PM11/2/22
to
On Wednesday, November 2, 2022 at 4:57:38 PM UTC-7, FortranFan wrote:
> Rather than the "hoped for", chances are high the Fortran committee will think the standard needs a quick fix here.

Thanks, but I think that I have what I need in order to classify this feature in the f18 documentation at https://github.com/llvm/llvm-project/blob/main/flang/docs/Extensions.md -- I wasn't sure whether it was an "extension" or a "standard feature that might as well not be".

Peter Klausler US

unread,
Nov 2, 2022, 8:23:40 PM11/2/22
to
On Wednesday, November 2, 2022 at 5:17:37 PM UTC-7, Steven G. Kargl wrote:
> > f18 prints " (1.,3.) (2.,3.)".
> What happens if you do
>
> program foo
> real, parameter :: a(2) = [1,2], b(3) = [1,2,3]
> print *, (a,b)
> end program foo

./t2.f90:3:10: error: Dimension 1 of left operand has extent 2, but right operand has extent 3
print *, (a,b)
^^^^^

Steve Lionel

unread,
Nov 2, 2022, 8:42:48 PM11/2/22
to
(I realize I meant to do a follow-up to the group and instead sent an
email to Peter...)

NAG Fortran does not accept this code. I can't find words in the
standard that either prohibit it, or assign it an interpretation.
Malcolm would say that means it's not allowed. I have asked him for his
thoughts, and suggested that a constraint should be added to require
that both parts be scalar (which NAG evidently believes is the rule.)

Another possibility, which I don't like but Peter seems to want, is that
if both are arrays that they be the same shape and if only one is scalar
that it gets duplicated to the shape of the other. This feels messy to me.
--
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

Peter Klausler US

unread,
Nov 2, 2022, 9:03:40 PM11/2/22
to
On Wednesday, November 2, 2022 at 5:42:48 PM UTC-7, Steve Lionel wrote:
> Another possibility, which I don't like but Peter seems to want, is that
> if both are arrays that they be the same shape and if only one is scalar
> that it gets duplicated to the shape of the other. This feels messy to me.

Many Fortran compilers support an extension feature "(a,b)" that is a generalized
complex constructor -- basically equivalent to CMPLX(a,b) except that the imaginary
part 'b' can't be a non-present optional dummy argument and the result type's kind being
automatically determined as it would be for "a+b". So some ordered pairs are
standard-conforming complex-literal-constants, and others are extension complex
constructors. The classification of the case in which one or both parts was a named
constant array is not clear, but it's either a complex-literal-constant or an extension
complex constructor to f18, and the result is the same either way, with the distinction
just being one of documentation.

Peter Klausler US

unread,
Nov 3, 2022, 1:04:57 PM11/3/22
to
A briefer way to explain "(a,b)" when it's not a complex-literal-constant is "(a)+(0,1)*(b)" with a & b constrained to be real or integer.

jfh

unread,
Nov 5, 2022, 4:10:57 AM11/5/22
to
The possibility that Peter wants and Steve thinks is messy is exactly what the cmplx intrinsic allows. Both the compilers I can use, ifort and gfortran, are happy with this program.

complex,parameter:: c(2) = cmplx([1.0,2.0], 3.0)
print *, c
end program

Of course both those compilers object, in different ways, if the word cmplx is removed from the above program.

John

unread,
Nov 5, 2022, 4:39:55 PM11/5/22
to
I have generally thought of (x,y) as equivalent to cmplx(x,y) without the issues with kind that cmplx() has with the restriction that the values are constant; and being that CMPLX is an elemental function I would have expected the same behavior between the two, personally. I also found it confusing in the past I could do

real,parameter :: x=3.0*3.0, y=sin(10.0)
complex :: z=(x,y)
complex :: zz=cmplx(3.0*3.0,sin(10.0))

but not

complex,parameter :: zzz=(3.0*3.0,sin(10.0))

as well, so I as a rule just use cmplx and always specify the kind anyway, even though it gets pretty verbose. Probably why the COMPLEX function is a common extension!

John

unread,
Nov 5, 2022, 4:48:46 PM11/5/22
to

John

unread,
Nov 5, 2022, 4:52:51 PM11/5/22
to
On Saturday, November 5, 2022 at 4:39:55 PM UTC-4, John wrote:
I just remembered an old argument about how some compilers allowed redundant parenthesis around expressions and how allowing anything but constants would break that, but just tried three compilers and none of them did so maybe that is a moot point. Does anyone know of a compiler that still allows something like "print *, (3+10*3)" printing a scalar integer, for example?

Steve Lionel

unread,
Nov 5, 2022, 7:09:53 PM11/5/22
to
On 11/5/2022 4:52 PM, John wrote:
> I just remembered an old argument about how some compilers allowed redundant parenthesis around expressions and how allowing anything but constants would break that, but just tried three compilers and none of them did so maybe that is a moot point. Does anyone know of a compiler that still allows something like "print *, (3+10*3)" printing a scalar integer, for example?

D:\Projects>type t.f90
print *, (3+10*3)
end
D:\Projects>ifort t.f90
Intel(R) Fortran Intel(R) 64 Compiler Classic for applications running
on Intel(R) 64, Version 2021.7.0 Build 20220726_000000
Copyright (C) 1985-2022 Intel Corporation. All rights reserved.

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

-out:t.exe
-subsystem:console
t.obj

D:\Projects>t.exe
33

D:\Projects>

I recognize the similarity to CMPLX, but am not sure the standard wants
to make complex constants elemental. I'm intending to write a paper and
see what the sense of the committee is on this. For F2023, which is in
the DIS stage, it would be simple to require the real and imaginary
parts to be scalar. Trying to do more at this point would risk
complications that often happen with last-minute expansions of semantics
- and it could be considered for F202Y.

John

unread,
Nov 5, 2022, 7:29:14 PM11/5/22
to
ifort was one of the ones I (mis)-tested. Was compiling a unicode file. So it would potentially break a lot of things to
allow for any form of expression, even a constant expression; potentially.

John

unread,
Nov 5, 2022, 7:45:29 PM11/5/22
to
On Saturday, November 5, 2022 at 7:09:53 PM UTC-4, Steve Lionel wrote:
> Email: firstname at firstnamelastname dot com program main
implicit none
print *, (3+10*3,0)
print *, (3+10*3)
print *, (3,0)
end program main

Have to say, the results with ifort and nvfortran were still surprising for the first print

33 0
33
(3.000000,0.0000000E+00)

But, as I mentioned, I quit using that syntax a long time ago.

Steve Lionel

unread,
Nov 5, 2022, 8:50:44 PM11/5/22
to
On 11/5/2022 7:43 PM, John wrote:
> implicit none
> print *, (3+10*3,0)
> print *, (3+10*3)
> print *, (3,0)
> end program main
>
> Have to say, the results with ifort and nvfortran were still surprising for the first print
>
> 33 0
Why? That's clearly a complex literal.

--
Steve Lionel
ISO/IEC JTC1/SC22/WG5 (Fortran) Convenor
Retired Intel Fortran developer/support
Email: firstname at firstnamelastname dot com

gah4

unread,
Nov 5, 2022, 10:46:17 PM11/5/22
to
On Saturday, November 5, 2022 at 4:45:29 PM UTC-7, John wrote:

(snip)

> implicit none
> print *, (3+10*3,0)
> print *, (3+10*3)
> print *, (3,0)
> end program main

The third is a complex constant.
The second is an expression in parens.

And the form that is supposed to not be allowed, in implied-DO without the implied-DO.


John

unread,
Nov 5, 2022, 11:27:56 PM11/5/22
to

John

unread,
Nov 5, 2022, 11:33:50 PM11/5/22
to
with list-directed output a complex value would appear at "(33.0,0.0)"; it printed as two integers. Being two (constant) expressions I actually expected an error. maybe that it would be an acceptable complex value, as it would have generated with CMPLX(); being in parenthesis I did not expect it to treat it at "print *, 3+10*3, 0".

John

unread,
Nov 5, 2022, 11:37:13 PM11/5/22
to
or maybe it treated it as "print *,(3+10*3,0,i=1,1)"

gah4

unread,
Nov 6, 2022, 12:59:32 AM11/6/22
to
On Saturday, November 5, 2022 at 8:37:13 PM UTC-7, John wrote:

(snip)

> or maybe it treated it as "print *,(3+10*3,0,i=1,1)"

This is my understanding.

Robin Vowels

unread,
Nov 6, 2022, 2:49:47 AM11/6/22
to
On Sunday, November 6, 2022 at 11:50:44 AM UTC+11, Steve Lionel wrote:
> On 11/5/2022 7:43 PM, John wrote:
> > implicit none
> > print *, (3+10*3,0)
> > print *, (3+10*3)
> > print *, (3,0)
> > end program main
> >
> > Have to say, the results with ifort and nvfortran were still surprising for the first print
> >
> > 33 0
.
> Why? That's clearly a complex literal.
.
3+10*3 looks like an expression to me, not a constant.

gah4

unread,
Nov 6, 2022, 7:03:56 AM11/6/22
to
On Sunday, November 6, 2022 at 12:49:47 AM UTC-7, Robin Vowels wrote:

(snip)

> 3+10*3 looks like an expression to me, not a constant.

It is a constant in C. I am not sure about Fortran, which is why this
question is so interesting.

Peter Klausler US

unread,
Nov 6, 2022, 1:00:47 PM11/6/22
to
On Saturday, November 5, 2022 at 5:50:44 PM UTC-7, Steve Lionel wrote:
> On 11/5/2022 7:43 PM, John wrote:
> > implicit none
> > print *, (3+10*3,0)
> > print *, (3+10*3)
> > print *, (3,0)
> > end program main
> >
> > Have to say, the results with ifort and nvfortran were still surprising for the first print
> >
> > 33 0
> Why? That's clearly a complex literal.

It is not a complex-literal-constant (R718) -- the real and imaginary parts would have to be both signed-int-literal-constant, signed-real-literal-constant, or named constants.

It is not a complex constant expression, either, in standard Fortran, for obvious reasons.

Steve Lionel

unread,
Nov 7, 2022, 9:14:25 AM11/7/22
to
On 11/6/2022 1:00 PM, Peter Klausler US wrote:
> It is not a complex-literal-constant (R718) -- the real and imaginary parts would have to be both signed-int-literal-constant, signed-real-literal-constant, or named constants.

Agree - I thought I posted a correction yesterday, but don't see it.

NAG Fortran rejects "print *, (3+10*3,0)". Intel Fortran accepts it as
it has an extension allowing a parenthesized I/O list - it will complain
if you ask for standards checking.

John

unread,
Nov 7, 2022, 8:01:15 PM11/7/22
to
Another thing the vexes me about complex variables is which compilers have it right for passing x%re and x%im as arguments?
I should probably report this to one or the other, but I cannot find anything in the standard so far that clears up "TEST II" so far.
Does anyone else see it?




$ gfortran x-x.f90
$ ./a.out
(100.000000,0.141120002)
(200.000000,0.141120002)

$ ifort x-x.f90
$ ./a.out
(100.0000,0.1411200)
(100.0000,0.1411200)

$ nvfortran x-x.f90
$ ./a.out
(100.0000,0.1411200)
(100.0000,0.1411200)
$ cat x-x.f90

> program testit
> complex :: x
> ! TEST I
> ! x%re|mi can appear on the left-hand side of an assignment
> x%re=100.0
> x%im=sin(3.0)
>
> ! TEST II
> write(*,*)x
> ! it can be passed as a subroutine argument and be changed
> call trivial(x%re)
> write(*,*)x
> contains
> subroutine trivial(r)
> real :: r
> r=r*2
> end subroutine trivial
> end program testit

Steven G. Kargl

unread,
Nov 8, 2022, 8:19:58 PM11/8/22
to
I believe that gfortran is correct.


9.1 Designator

R901 designator is object-name
or array-element
or array-section
or coindexed-named-object
or complex-part-designator
or structure-component
or substring

1 The appearance of a data object designator in a context that requires its value
is termed a reference.

9.2 Variable is designator

R902 variable

There is nothing in

19.6.5 Events that cause variables to become defined

1 Variables become defined by the following events.

the long list that disqualifies a complex-part-designator
from being manipulated through the argument association
with a dummy argument.



John

unread,
Nov 9, 2022, 9:24:08 AM11/9/22
to
Exactly what I was looking for. Two out of three compilers I tried did not agree with what I expected, and I did not see what, when you extract and present it as you did, suddenly looks (relatively) clear. I will report to Intel and Nvidia. Curious if anyone has results for NAG/Cray/IBM/...

Steve Lionel

unread,
Nov 9, 2022, 10:39:49 AM11/9/22
to
On 11/9/2022 9:24 AM, John wrote:
> Curious if anyone has results for NAG/Cray/IBM/...
D:\Projects>nagfor -o t.exe t.f90
NAG Fortran Compiler Release 7.1(Hanzomon) Build 7114
[NAG Fortran Compiler normal termination]

D:\Projects>t.exe
(1.0000000E+02,0.1411200)
(2.0000000E+02,0.1411200)

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

jfh

unread,
Nov 9, 2022, 3:21:49 PM11/9/22
to
On renaming the program xreim.f90 and making the dummy argument r of subroutine trivial intent(inout) ifort gave this compile-time error message:

xreim.f90(11): error #6638: An actual argument is an expression or constant; this is not valid since the associated dummy argument has the explicit INTENT(OUT) or INTENT(INOUT) attribute. [REAL]
call trivial(x%re)
^
compilation aborted for xreim.f90 (code 1)

That made it clearer why ifort did what it did. Whether it was standard-conforming is a more subtle question.

John

unread,
Nov 11, 2022, 9:02:54 PM11/11/22
to
FYI: Reported issues with complex designators on Intel Forum ...

https://community.intel.com/t5/Intel-Fortran-Compiler/Issues-with-complex-part-designators/m-p/1429557#M163510

Did anyone ask J3 for clarification on original issue?


Steve Lionel

unread,
Nov 12, 2022, 2:19:01 PM11/12/22
to
Unnecessary - the standard is quite clear that a complex-part-designator
is a variable. That ifort doesn't treat it that way is a bug.

John

unread,
Nov 16, 2022, 8:56:34 PM11/16/22
to
FYI: Intel and the Intel forum were very responsive and Intel has opened 2 bug reports on the complex designator issues

CMLRLLVM-41931 for passing z%re to a subroutine that updates the value of the arg, but actual arg is unchanged after return.

CMLRIL0-35035 for the -check uninit that erroneously flags the assignment as illegal use of uninit variable.
> WG5: https://wg5-fortran.org
0 new messages