Qml test with large int values unstable in debug
-
Hello,
I am using qmltestrunner for some test application and came across a difference in behavior between release and debug build when dealing with large int values.
The test is the following:
tst_large-int.qmlimport QtQuick 2.5 import QtTest 1.0 TestCase { name: "large-int" function test_large_int(data) { var act = 0xA5000000; var exp = '2768240640'; compare(act.toString(), exp); } }
And the application used
main.cpp -> ut-qml-large-int.exe#include <QQmlApplicationEngine> #include <QtQuickTest> int main(int argc, char *argv[]) { return quick_test_main(argc, argv, "ut_qml", 0); }
The command used to run the test is:
ut-qml-large-int.exe -input tst_large-int.qml
When the application is built in release and run with the command above, the test executes correctly every time.
execution 1:********* Start testing of ut_qml_large_int ********* Config: Using QtTest library 5.8.0, Qt 5.8.0 (i386-little_endian-ilp32 shared (dynamic) release build; by GCC 5.3.0) PASS : ut_qml_large_int::large-int::initTestCase() PASS : ut_qml_large_int::large-int::test_large_int() PASS : ut_qml_large_int::large-int::cleanupTestCase() Totals: 3 passed, 0 failed, 0 skipped, 0 blacklisted, 11ms ********* Finished testing of ut_qml_large_int *********
execution 2:
********* Start testing of ut_qml_large_int ********* Config: Using QtTest library 5.8.0, Qt 5.8.0 (i386-little_endian-ilp32 shared (dynamic) release build; by GCC 5.3.0) PASS : ut_qml_large_int::large-int::initTestCase() PASS : ut_qml_large_int::large-int::test_large_int() PASS : ut_qml_large_int::large-int::cleanupTestCase() Totals: 3 passed, 0 failed, 0 skipped, 0 blacklisted, 11ms ********* Finished testing of ut_qml_large_int *********
But when the same application is built in debug and run with the same command, the first execution is a success but all the following are failed.
execution 1:********* Start testing of ut_qml_large_int ********* Config: Using QtTest library 5.8.0, Qt 5.8.0 (i386-little_endian-ilp32 shared (dynamic) debug build; by GCC 5.3.0) PASS : ut_qml_large_int::large-int::initTestCase() PASS : ut_qml_large_int::large-int::test_large_int() PASS : ut_qml_large_int::large-int::cleanupTestCase() Totals: 3 passed, 0 failed, 0 skipped, 0 blacklisted, 13ms ********* Finished testing of ut_qml_large_int *********
execution 2:
********* Start testing of ut_qml_large_int ********* Config: Using QtTest library 5.8.0, Qt 5.8.0 (i386-little_endian-ilp32 shared (dynamic) debug build; by GCC 5.3.0) PASS : ut_qml_large_int::large-int::initTestCase() FAIL! : ut_qml_large_int::large-int::test_large_int() Compared values are not the same Actual (): -5.386372713960645e+214 Expected (): 2768240640 ...\qtc_Desktop__f4d5050c-debug\install-root\ut-qml-large-int\bin\tst_large-int.qml(12) : failure location PASS : ut_qml_large_int::large-int::cleanupTestCase() Totals: 2 passed, 1 failed, 0 skipped, 0 blacklisted, 14ms ********* Finished testing of ut_qml_large_int *********
Is it something explicable?
How to get everytime success in debug? -
I'm slightly suspicious of the fact that 0xA5000000 = 2768240640 overflows a regular 32 bit signed integer. Whether that's taking you into "undefined behaviour" territory I have no idea. Possibly your issue is related to JS "numbers" sometimes being 32-bit ints and sometimes 64-bit floats though.
-
Sorry don't know nearly enough about gnarly details of JS to comment further. You might find https://stackoverflow.com/questions/3885817/how-do-i-check-that-a-number-is-float-or-integer interesting though.
One thing I have come across (in webdev world) is people writing things like
var y=x|0
to force something to integer (the output of the bitwise|
operator is guaranteed to be an int). Apparently tricks like that you can get big performance improvements in JS systems using JIT compilation by helping the compiler "know" what the types the code generated will be dealing with. -
@vivi
mmh, have you seen this stackoverflow thread?
compare seems like it would use bitwise operations. Could be the reason for the behavior.