- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Can you post the code so that people can reproduce the problem? Without it we can only speculate.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The code:
real*4 FUNCTION AREABU (idxOFlange, idxIFlange, idxWeb, D, holes, tl, isARafter)
implicit none
integer idxOFlange, idxIFlange, idxWeb
real*4 D
integer holes, tl, isARafter
real*4 bf /0.0/, tf/0.0/, bf2/0.0/, tf2/0.0/, tw /0.0/
real*4 girtBoltDiameter /0.5/, purlinBoltDiameter /0.5/
type(web_data), pointer :: webPtr
ifPtr => flange(idxIFlange)
bf = ifPtr.width
tf = ifPtr.thickness
ofPtr => flange(idxOFlange)
bf2 = ofPtr.width
tf2 = ofPtr.thickness
webPtr => web(idxWeb)
tw = webPtr.thickness
if (holes) then
if (tl) then
if (isARafter) then
net = bf2 - 2.0 * (purlinBoltDiameter + 0.0625)
else
net = bf2 - 2.0 * (girtBoltDiameter + 0.0625)
end if
bf2 = min(bf2, 5.0/6.0 * ofPtr.Fu/ ofPtr.Fy * net)
else
if (isARafter) then
net = bf - 2.0 * (purlinBoltDiameter + 0.0625)
else
net = bf - 2.0 * (girtBoltDiameter + 0.0625)
end if
bf = min(bf, 5.0/6.0 * ifPtr.Fu/ ifPtr.Fy * net)
end if
end if
RETURN
END
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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".
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
This is the simplified calling code:
real*4 d, sarea
integer isFalse
isFalse = 0
sarea = AREABU(ele.bu_oflange.index, ele.bu_iflange.index, ele.bu_web.index, d, isFalse, isFalse, isFalse)
Some definitions:
record /eleprops/ ele
structure/eleprops/
union
map
real*4 bu_D1, bu_D2, bu_minweb, bu_minflange
record/invmap/ bu_oflange, bu_web, bu_iflange
end map
. . .
structure/invmap/
integer*2 type, index
end structure
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
fourreal wrote:
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
>>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?
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
structure/eleprops/
union
map
real*4 bu_D1, bu_D2, bu_minweb, bu_minflange
record/invmap/ bu_oflange, bu_web, bu_iflange
end map
...
integer*2 type, index
end structure
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
The call:
sarea = AREABU()
The function:
real*4 FUNCTION AREABU ()
implicit none
integer*4 idxOFlange, idxIFlange, idxWeb
real*4 D
logical*4 holes, tl, isARafter
real*4 bf /0.0/, tf/0.0/, bf2/0.0/, tf2/0.0/, tw /0.0/
real*4 girtBoltDiameter /0.5/, purlinBoltDiameter /0.5/
tl = .false.
isARafter = .false.
bf = 5.0
tf = 0.3125
bf2 = 5.0
bf2 = 0.3125
tw = 0.1875
D = 27.75
if (tl) then
if (isARafter) then
net = bf2 - 2.0 * (purlinBoltDiameter + 0.0625)
else
net = bf2 - 2.0 * (girtBoltDiameter + 0.0625)
end if
bf2 = min(bf2, 5.0/6.0 * 70/55 * net)
else
if (isARafter) then
net = bf - 2.0 * (purlinBoltDiameter + 0.0625)
else
net = bf - 2.0 * (girtBoltDiameter + 0.0625)
end if
bf = min(bf, 5.0/6.0 * 70/55 * net)
end if
end if
RETURN
END
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Same invalid FP failure:
REAL*4 FUNCTION AREABU ()
AREABU = 9.999
RETURN
END
Is it possible to simplify this? Maybe I should try punch cards?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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, ....
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
#14>> The integer type are all *2, although I have experimented with *4.
#4>> integer idxOFlange, idxIFlange, idxWeb
#4>>...
#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.
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I reduced the call to:
sarea = AREABU()
and the function to:
REAL*4 FUNCTION AREABU ()
AREABU = 9.999
RETURN
END
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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 16.0.4.246 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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Program test implicit none real(4) :: sarea real(4), external :: AREABU sarea = AREABU() print *, sarea end REAL*4 FUNCTION AREABU () AREABU = 9.999 RETURN END
The above program compiles and runs just fine. So what is different in your test case which we have not seen. If your test case is built into an application I would suggest that the stack has already been corrupted by some problem unrelated to AREABU. Do you have run time option /check:stack on compilation?
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page