I've just upgraded to Fortran 2016 from 2013 and now throw a floating point invalid operation exception 0x90. The error is trapped at the declaration of a function. I've reduced to the parameter list to a few reals and integers, and the parameters look good before the function is called and at the top of the function. The exception is thrown before the first executable statement of the function.
I have tried different /fpe settings, debug & release, and throwing salt over my shoulder. Any help would be appreciated.
Windows 10, Visual Studio 2015
I'll have to reformat the build log from html to txt before I'm allowed to upload it.
You can place files of any type into a Zip file and attach the Zip file in your response.
You use the options /Qsave /align:commons /Qtrapuv /Qinit:zero. If you are debugging code, especially code written in recent decades, /Qsave and /Qinit:zero should not be used -- they hide lots of bugs. Furthermore, after you use these options, /Qtrapuv will trap nothing that I can think of, since you have replaced uninitialized variables, if any, by zero.
The net effect of using bug-hiding options such as these with buggy code is to make finding the bugs much harder, and possibly to hide the bugs for decades if these options are also used in compiling production code.
From the description, "The error is trapped at the declaration of a function", I gather that you observed the code in a symbolic debugger. But, since declarations are not executable statements, the actual location of the FPE is somewhere nearby, either in the code that sets up the call, or in the code near the beginning of the routine.
Since we run code every day that matches your description and runs without triggering FPEs, there must be some specific problem with your particular code. As Arjen said, you will need to provide sample code or, even better, a complete reproducer.
real*4 FUNCTION AREABU (idxOFlange, idxIFlange, idxWeb, D, holes, tl, isARafter)
That is one part, the next one is: what does the code look like that calls the routine? Please try to make it so that we can create a program from this - a "reproducer".
Does this function crash the first time it is called? real*4 net /0.0/, for example net is reasssigned so may not be zero or may be uninitialised dependant upon compiler options on a subsequent call. the dot in ifPtr.width is not standard fortran it should be a % BTW.
Because your code contains user-defined types, which I presume are declared in the include file "inv.h", not much can be said or done unless the include file is provided.
This is the simplified calling code:
real*4 d, sarea
isFalse = 0
sarea = AREABU(ele.bu_oflange.index, ele.bu_iflange.index, ele.bu_web.index, d, isFalse, isFalse, isFalse)
record /eleprops/ ele
real*4 bu_D1, bu_D2, bu_minweb, bu_minflange
record/invmap/ bu_oflange, bu_web, bu_iflange
. . .
integer*2 type, index
The function does crash the first time it is called. And the code is profuse with the dot notation for structures.
This is actually the second version of the crashing function, the original being AREA. I created it to experiment with different ways of trying to dodge the FP error. The original AREA, called from other places, sometimes runs and sometimes crashes. It's possible that the original function has executed unaltered since 1987.
The fragments of information that you added do not serve to give us a complete picture. Rather, they raise more questions. I could speculate that your code has some undefined variables (or undefined components of your non-standard structures), and their presence has gone unnoticed until now.
It's possible that the original function has executed unaltered since 1987.
Not likely since the pointer and derived types stuff is Fortran 90. You have quite a mishmash of non-standard and obsolete things in your code. When you do that some unforeseen (undefined) things can rear their heads and bite you. Having worked in the past in this instance is no guarantee of working in the future . I recall a recent bugfix relating to use of . rather than % for example. Logical tests on integers rather than logicals is also not good practice.
It is hard to know what is wrong, you really need to make a small but complete sample that reproduces the problem and then you will get better answers rather than guesses.
The failure occurred before the addition of the pointers. The data fields were accessed in a more traditional manner. The integers used as logicals were a grasping-at-straws measure because the VS debugger local watch lists logical as ??? but integers as shorts. These have been returned to being logicals.
>>ele.bu_oflange.index, ele.bu_iflange.index, ele.bu_web.index
Is, and how is, ele, ele.bu_oflang, eld.bu_iflange, ele.bu_web defined?
IOW is ele an allocatable or pointer .not. defined?
and/or member objects/structures of ele: bu_... allocatable or pointer .not. defined?
and/or what are the integer types (1, 2, 4, 8) of the respective index of those member objects/structures?
Have you enabled the compile time diagnostics to generate and warn on invalid interfaces?
I've reduced the function to intrinsic variable types and hard wired data. There are no parameters. The behavior is the same - F10 off the function declaration and throw a Floating-point invalid exception.
sarea = AREABU()
real*4 FUNCTION AREABU ()
interesting! But, there is usually a simple answer. Can you post a complete example that fails and also the buildlog so we can also see what options are used. There are still a long list of potential causes...
How Is AREABU() declared in the caller? Is it declared external, is it in a module, ....
#14>> The integer type are all *2, although I have experimented with *4.
#4>> integer idxOFlange, idxIFlange, idxWeb
#4>> integer holes, tl, isARafter
The Dummy (integer) arguments to function AREABU are declared as default INTEGER. Unless an option switch overrides this, these are declared as INTEGER(4). FORTRAN is call by reference. Without a function interface (not required), the call will not promote your INTEGER(2) reference into INTEGER(4). Effectively, without an interface, the references to your caller's INTEGER(2) will be treated as INTEGER(4). IOW they will overlap. This in turn will cause the dereference of idxOFlange, idxIFlange, idxWeb to read in two bytes following the actual arguments (as additional precision), thus (likely) causing index out of range.
#16>>Same invalid FP failure: REAL*4 FUNCTION AREABU ()
Did your call, call with no arguments?
Is AREABU in a .LIB or .DLL?
Note, these questions would be easily answered by you supplying a simple (complete) reproducer.
I reduced the call to:
sarea = AREABU()
and the function to:
REAL*4 FUNCTION AREABU ()
AREABU = 9.999
This is all tucked inside a DLL. The debugger will step to the FUNCTION statement. Stepping off the FUNCTION statement generates a floating point invalid operation exception. This happens without a floating point operation - not even an assignment. No parameters are passed so I can't corrupt or misalign a call list. There are no integers, default or otherwise. There are no logicals. I don't have a language issue. Can I eliminate a linker issue? I'll guess it's a compiler issue.
So far (19 posts already!) you have not established that there is a compiler issue. Here is a non-reproducer that serves only to demonstrate that your list of attributes and features is insufficient to enable the problem, if there exists one, to be investigated. It is based on your statements.
The DLL code:
c REAL*4 FUNCTION AREABU () AREABU = 9.999 RETURN END c
The program that calls the DLL:
c program parea implicit none real AREABU, S S = AREABU() print *,' S = ',S end c
I built the DLL and the EXE using the 18.104.22.168 compiler for X64 on Windows 10.
ifort /LD /Zi areabu.f /link /export:AREABU ifort /Zi parea.f areabu.lib
Running the resulting EXE in the debugger displays completely normal, if boring, behavior. No exceptions of any kind, one line of output with expected result.
I hope that you can see from this counter-example that we really need a reproducer from you. The ball is very much in your court.