Opened 13 years ago
Closed 13 years ago
#222 closed defect (fixed)
Instantiating QApplication modifies floating point control word.
Reported by: | rudi | Owned by: | |
---|---|---|---|
Priority: | major | Milestone: | Qt 4.7 |
Component: | QtGui | Version: | |
Severity: | high | Keywords: | |
Cc: |
Description
The following code:
int main(int argc, char *arg[]) { qDebug("FCW: %04x", _control87(0, 0) ); QApplication a(argc, argv); qDebug("FCW: %04x", _control87(0, 0) ); ... }
produces:
FCW: 037f FCW: 0367
I.O.W., it enables floating point overflow and underflow exceptions. I don't think that this should happen.
Change History (9)
comment:1 by , 13 years ago
comment:2 by , 13 years ago
Resolution: | → wontfix |
---|---|
Status: | new → closed |
This is a very old problem of OS/2. AFAIR, some GPI calls change FCW and then do not restore it back. There is a workaround for that in qdtoa() (there is a similar problem on Windows BTW). If we want to solve it globally we will have to write wrappers for all GPI (and probably Win*) calls which I consider as an overkill -- if you need a particular value of FCW for your code just go the qdtoa() way.
So unless you have a very good argument to do wrappers there is nothing we can do about this problem.
Thank you for reporting anyway.
comment:3 by , 13 years ago
Resolution: | wontfix |
---|---|
Status: | closed → reopened |
Actually it's the call to WinCreateMsgQueue() that is causing this particular problem. I strongly suggest to either add a local workaround to qeventdispatcher_pm.cpp or change API_FPU_CW_Wrappers.h.
For testing I did reset the FCW after WinCreateMsgQueue(). This change made QtDeclarative / QMLVIEWER work without the need for source code modifications as mentioned in #221. I have not yet tried to revert the sources for QtCreator's QMLJS.DLL, but I suspect with this change it will work out of the box as well.
comment:4 by , 13 years ago
Okay, recalled the whole wrappers thingy (#105). Yes, in this case the correct way is to modify API_FPU_CW_Wrappers.h (as your modifications to QtDeclarative are too hackish indeed). I will just save the FCW before each Win* call and then restore it afterwards. (Now the code simply disables the "division by zero" exception and leaves the under/overflow bits intact).
comment:5 by , 13 years ago
Hehe, not more hackish than the original, I'd say ;-). They rely on the assumption that "double" is the largest member of the union which is also a questionable approach.
BTW, I suggest to change API_FPU_CW_Wrappers.h like this:
inline unsigned __fstcw(void) { unsigned out; asm volatile ( "fstcw %0\n\t" : "=m" (out) ); return out; } inline void __fldcw(unsigned in) { asm volatile ( "fldcw %0\n\t" : : "m" (in) ); } #define __FPU_CW_SAVE unsigned fcwState = __fstcw(); #define __FPU_CW_RESTORE __fldcw(fcwState); inline BOOL APIENTRY __FPU_CW_WinCancelShutdown (HMQ hmq, BOOL fCancelAlways) { __FPU_CW_SAVE BOOL ret = WinCancelShutdown (hmq, fCancelAlways); __FPU_CW_RESTORE return ret; } #define WinCancelShutdown __FPU_CW_WinCancelShutdown ...
IMHO, this generates the most efficient code. GCC's inline assembler is always fun...
Update: I had to change the code a bit to make it work correctly with GCC335. However, GCC4 produces better output.
comment:7 by , 13 years ago
I'm not sure if anyone is going to work on Qt3. However, I fixed the code snippet above to be compatible with the GCC that is used to compile Qt3.
comment:8 by , 13 years ago
Andy, as we are not updating qt3 at all feel free to include your changes to this official tree. or just provide a custom qt3.
if you need svn write access let me know.
comment:9 by , 13 years ago
Resolution: | → fixed |
---|---|
Status: | reopened → closed |
Fixed in r873. Thanks for finding that out.
Just to add: Qt 4.6.3 behaves identical.