Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.

Why "This operator is invalid in a constant expression"

Brian_Murphy
New Contributor II
1,034 Views
stop ('Zero or negative CMS modal mass for LINE number ' // trim(inum2str(iline)) )

I don't understand why the above line generates the following compile error:

Transf.f90(306): error #6264: This operator is invalid in a constant expression evaluation.   [TRIM]

This code compiled with no error in visual studio 2010 & XE 2013 but not when I opened the .sln in visual studio 2019 & XE 2020.  If I take out the "trim", the same error message occurs but names inum2str as the offender.

I doubt inum2str is the problem, but it is as follows:

function inum2str( num )
	integer num
	character(32) inum2str
	write(inum2str,'(i0)') num
end function

I found this google thread that suggests it might be a compiler bug.  I get another weird compile error with this file that goes away if I comment out the above line.  That error is error #5508: Declaration of routine 'GET_X_AX_STN' conflicts with a previous declaration even though there isn't a previous declaration.

 

0 Kudos
8 Replies
andrew_4619
Honored Contributor II
1,034 Views

Can the call to inum2str see an interface to that function? If not  it has no idea that that function returns type character and hence the error message.

0 Kudos
Brian_Murphy
New Contributor II
1,034 Views

Most of this code was written before the days of interfaces.  Could there be an incompatibility between the XE 2013 and 2020 compilers?

I have worked around the error by changing it to the following:

write(*,*) ('Zero or negative CMS modal mass for LINE number ' // trim(inum2str(iline)) )
stop 'program execution aborted'

Documentation for the STOP statement includes A scalar character constant expression of type default character.  But still, XE 2013 allowed it.

I will consider this problem solved.  This particular file will now compile, but the project which would build in XE2013 still will not build in XE2020.  I will start another thread for the next problem.

0 Kudos
Steve_Lionel
Honored Contributor III
1,034 Views

Fortran 2008 requires the "stop-code" to be a scalar constant expression, either default-character or integer. TRIM is allowed only when its argument is also a constant expression. Fortran 2018 allows any scalar default character or integer expression, so your code above is valid F2018 but not F2008.

If it is true that older compilers accepted that, which I am skeptical of, it was a missing error check that allowed it.

0 Kudos
FortranFan
Honored Contributor II
1,034 Views

Brian Murphy wrote:

.. This code compiled with no error in visual studio 2010 & XE 2013 but not when I opened the .sln in visual studio 2019 & XE 2020...

Perhaps the compiler implementation in XE 2013 was way ahead of its time!!  'cause it's only in Fortran 2018 the STOP and ERROR STOP statements are allowed to expressions of scalar integer and character type that are not constant.

stop.PNG

For whatever it's worth, the standard does not indicate parentheses as being valid syntax on the 2 stop statements.

0 Kudos
jimdempseyatthecove
Honored Contributor III
1,034 Views

FF or Steve

Can you elaborate the QUIET=.false. (or omitted) as to exceptions signaling and unit identified? Perhaps with example.

I can envision how this can be implicitly used in conjunction with an I/O statement without an ERR=... but what happens with an ERROR STOP that is not associated with a signaling exception .NOR. as a result of an error inducing I/O statement (with ERR= ).

Jim Dempsey

0 Kudos
Steve_Lionel
Honored Contributor III
1,034 Views

As the creator of the QUIET= feature, I can certainly comment on that.

First of all, this affects only STOP and ERROR STOP statements you put in your program. In Fortran 2008, the standard says what F2018 says in paragraph 3 above - if there are any currently signaling [floating point] exceptions, a message will be displayed on stderr saying so, before terminating. There is no effect on I/O or other kinds of errors.

F2018 allows you to disable that warning, and also to suppress any message that the processor would otherwise emit for the STOP or ERROR STOP. Traditionally, a STOP would display something like "FORTRAN STOP" on stderr, though the standard didn't say it had to. If there was a "stop code', that would be "made available" somehow, usually as part of a message to stderr.

In F2018, you can now say QUIET= to disable that stderr output - there will be no output from STOP or ERROR STOP themselves.

Note that I highlighted floating point exceptions. These are the ONLY "exceptions" recognized by standard Fortran, and you'd want to read the chapters on the IEEE floating point intrinsic modules for more on that. There is a concept of an exception being signaled that doesn't necessarily result in the program stopping. You can set the behavior with calls to IEEE module procedures. 

 

0 Kudos
jimdempseyatthecove
Honored Contributor III
1,034 Views

In the case of a signaling (FPU) exception, would you also have to have installed an IEEE_HANDLER?

BTW IMHO the exception handling is lacking functionality. By this I mean the SOP is for the handler to display an optional alternate message, perform any cleanup, then abort the program. IOW it appears that there is no means to provide error recovery (except for IEEE error poling of non-signaling events after each statement that could cause an error).

**** CAUTION suggested feature request follws ****


    result = IEEE_HANDLER (action, exception, handler[, recoverLineOrTag])

Where when optional argument recoverLineOrTag is specified, the stack frame prior to this call is preserved, and the return from the handler returns to the specified line or tag with the restored stack frame. The programmer would have the responsibility of assuring the return point is in the proper stack context.

What this would permit you to do is to recover from say a divide by zero (even in vectorized code) and provide an alternate result to meet your needs. You could do this without poling IEEE status in you inner loop. It would mean that your loop would need to maintain a progress indicator for the recovery code to recover from the error.

Jim Dempsey

0 Kudos
Steve_Lionel
Honored Contributor III
1,034 Views

Standard Fortran doesn't have the concept of handlers. You are absolutely correct that the language is missing exception handling. This was proposed for Fortran 202X, but there was widespread disagreement on what the scope of that would be and it got removed from the work plan. The main problem is that no two people seem to be able to agree on what a handler ought to do and how we could define it in a way that didn't require ALL Fortran code to slow down. I would very much like to see if we can resolve this for the following revision that we're calling Fortran 202Y.

By the way, if you are interested in future standard features, please check out https://github.com/j3-fortran/fortran_proposals/issues which is being used to collect ideas for the next revision.

0 Kudos
Reply