Bug? Bugs in B4A V 10

Alex_197

Well-Known Member
Licensed User
Longtime User
In php you can compare different types. In legacy VB from MS Visual Studio (in which it's supposed to be based B4A either). In Pascal and Fortran its possible also. In the "died" C Builder from Borland it's possible also.
Mod - keep it simple.
 

Semen Matusovskiy

Well-Known Member
Licensed User
I don't remember any Basic dialect, when it was neccessary to worry about numeric comparisons. It's a matter of compiler. If there are integer and float/double variables, it should convert integer values to float/double.
 

Marcos Alves

Well-Known Member
Licensed User
Longtime User
I don't remember any Basic dialect, when it was neccessary to worry about numeric comparisons. It's a matter of compiler. If there are integer and float/double variables, it should convert integer values to float/double.
Implict conversion, that's how we used to call this feature.
 

Marcos Alves

Well-Known Member
Licensed User
Longtime User
I don't remember any Basic dialect, when it was neccessary to worry about numeric comparisons. It's a matter of compiler. If there are integer and float/double variables, it should convert integer values to float/double.
But my main worry is: where in my dozens of B4A apps I used this kind of comparison, and where I'll have a problem if I use the new B4A to compile. This will be a BIG problem!
 

Star-Dust

Expert
Licensed User
Longtime User
Objective: discover if a number is divisible by other:

Approach 1: use the "int" command (which doesn't exist in B4A): ex: if (a/b) = int(a/b) then log('OK')

Approach 2: store the result in a int variable and compare:
Dim r as int = (a/b)
if r = (a/b) then log('OK')

that's what I mean. 👍 ;)

B4X:
    if (a/b) = Floor(a/b) then log('OK')
or
B4X:
    if (a/b) = Round(a/b) then log('OK')
 
Last edited:

OliverA

Expert
Licensed User
Longtime User
I used following code
B4X:
    Log($"======================== Run 1 ${DateTime.Now} ==========================="$)
    Dim intLine As Int
    Dim lineMod As Double
    For i = 0 To 80
        intLine = i/20
        lineMod  = i /20
        If lineMod = intLine Then
            Log($"${lineMod}=${intLine}"$)
        End If
    Next
    For i = 0 To 80
        intLine = i/20
        lineMod  = i /20
        If intLine = lineMod Then
            Log($"${intLine}=${lineMod}"$)
        End If
    Next

It looks like this issue only happens in Debug mode. When you run this code for the first time, and for subsequent times IF you leave the code unchanged, it will produce the correct output.
======================== Run 1 1594924125738 ===========================
0.0=0
1.0=1
2.0=2
3.0=3
4.0=4
0=0.0
1=1.0
2=2.0
3=3.0
4=4.0

If you then change the max i to another number, everything gets screwed up (changed max i to 20)
======================== Run 1 1594924378694 ===========================
0.0=0
1.0=1
2.0=2
0=0.0
0=0.05
0=0.1
0=0.15
0=0.2
0=0.25
0=0.3
0=0.35
0=0.4
0=0.45
0=0.5
0=0.55
0=0.6
0=0.65
0=0.7
0=0.75
0=0.8
0=0.85
0=0.9
0=0.95
1=1.0
1=1.05
1=1.1
1=1.15
1=1.2
1=1.25
1=1.3
1=1.35
1=1.4
1=1.45
1=1.5
1=1.55
1=1.6
1=1.65
1=1.7
1=1.75
1=1.8
1=1.85
1=1.9
1=1.95
2=2.0
If you do a "Clean Project", everything seems to work as expected:
=== Run 1 1594924473043 ===========================
0.0=0
1.0=1
2.0=2
0=0.0
1=1.0
2=2.0

If you run the examples in Release mode, the results are always as you expect them.
Please note, the produced code for the comparison is
Java:
if (_intline==_linemod) {

According to Java rules, the int value is promoted to a double in a comparison (https://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html#jls-5.6.2). Currently, your comparisons work, even though they are double's, since we are dealing with small numbers. If you had to compare a relatively large integer to the division of two doubles, things may still go wrong (the integer converted to a double is not the same as the division of two doubles, due to how doubles work).

So in the end, this has nothing to do with object comparison or on which side of the comparison the int/double is. It's just something weird in the debugger/with debugging.
 

Marcos Alves

Well-Known Member
Licensed User
Longtime User
I used following code
B4X:
    Log($"======================== Run 1 ${DateTime.Now} ==========================="$)
    Dim intLine As Int
    Dim lineMod As Double
    For i = 0 To 80
        intLine = i/20
        lineMod  = i /20
        If lineMod = intLine Then
            Log($"${lineMod}=${intLine}"$)
        End If
    Next
    For i = 0 To 80
        intLine = i/20
        lineMod  = i /20
        If intLine = lineMod Then
            Log($"${intLine}=${lineMod}"$)
        End If
    Next

It looks like this issue only happens in Debug mode. When you run this code for the first time, and for subsequent times IF you leave the code unchanged, it will produce the correct output.


If you then change the max i to another number, everything gets screwed up (changed max i to 20)

If you do a "Clean Project", everything seems to work as expected:


If you run the examples in Release mode, the results are always as you expect them.
Please note, the produced code for the comparison is
Java:
if (_intline==_linemod) {

According to Java rules, the int value is promoted to a double in a comparison (https://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html#jls-5.6.2). Currently, your comparisons work, even though they are double's, since we are dealing with small numbers. If you had to compare a relatively large integer to the division of two doubles, things may still go wrong (the integer converted to a double is not the same as the division of two doubles, due to how doubles work).

So in the end, this has nothing to do with object comparison or on which side of the comparison the int/double is. It's just something weird in the debugger/with debugging.
Hello @OliverA ... like I told, It's a bug. More specifically, as you discovered, it's a bug in debug framework of B4A (bug in debug ??? Funny 😂 ) ...
 

OliverA

Expert
Licensed User
Longtime User
Erel make it to work in B4x, but comparing different type is not posible in any other language that I know.
Lots of languages do implicit type casting for you. One usually needs to know when a language does this, because these implicit castings can bite one. Maybe Kotlin eschewed implicit casting for that reason (Note: I do not know Kotlin and maybe the case you pointed out is not such a case).

More specifically, as you discovered, it's a bug in debug framework of B4A
I'm actually glad it's not in a new way of handling primitive type comparisons. That would have caused chaos (and I started to get a little nervous). But then, @Erel would not do that to us. The object comparison issue mentioned earlier is a different issue.
 

OliverA

Expert
Licensed User
Longtime User
In case someone else want to try, here is the primitive project that I used to test the issue
 

Attachments

  • 20200716_DoubleInt.zip
    8.2 KB · Views: 140

OliverA

Expert
Licensed User
Longtime User
older version of B4A? Did it behave differently?
Tested with 9.80. Two differences: 1) It works properly 2) Subsequent runs seem to run a lot faster than with 10.0. 10.0 seemed to have a noticeable lag when executing this simple app repeatedly.
 

Marcos Alves

Well-Known Member
Licensed User
Longtime User
Tested with 9.80. Two differences: 1) It works properly 2) Subsequent runs seem to run a lot faster than with 10.0. 10.0 seemed to have a noticeable lag when executing this simple app repeatedly.
Yes!!! I noticed this lag also - this is well documented in this post: https://www.b4x.com/android/forum/t...rong-with-debugger-in-v10.120261/#post-752009

basically: cleaning the project and running the first time with debug - intensive sql routine spends 1 second to run
- If the module is edited / updated after run: the SAME routine spends 41 seconds !
 

Marcos Alves

Well-Known Member
Licensed User
Longtime User
Yes!!! I noticed this lag also - this is well documented in this post: https://www.b4x.com/android/forum/t...rong-with-debugger-in-v10.120261/#post-752009

basically: cleaning the project and running the first time with debug - intensive sql routine spends 1 second to run
- If the module is edited / updated after run: the SAME routine spends 41 seconds !
It's very complicated to use B4A 10... the app that I'm developing spends about 48 seconds to compile from scratch. If I use rapid debug after code editing it spends 5-6 seconds but has a lag that increases the running time from 1 second to about 55 seconds ! This means that each time when I change the code, if I want to test, I must to choose between to clean the project and spend 55 seconds to compile again (running in 1 second), or use the fast debug and wait 55 seconds to finish the routine. Crazy !!!!
Help @Erel please !!!!:eek:
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
Crazy !!!!
Help @Erel please !!!!
This is not the correct way to get support. I'm continuing this discussion with Oliver.

@OliverA can you post the logs in debug mode, running in v9.80 and in v10.0 and also add some timing outputs? You can put a breakpoint at the end of the sub to force the debugger to use the slower execution pipeline.

Note that none of the new features in v10.0 is related to the debugger. Maybe something has changed in v9.90.
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
Here are my findings:

1. There is indeed an issue related to comparison of numbers with different types in the "rapid" execution pipeline. It is a result of a fix of a different bug (fixed a few months ago). The change will be reverted.
2. There is no change in the performance of the debugger. Some differences are related to the change discussed above however the numbers reported dramatically by Marcos are not related to this. As explained in the past, the debugger has two execution pipelines. Modified subs run on the slower pipelines. Also subs with breakpoints. Depending on the specific code, there are cases where the slow pipleline is just too slow and you need to clean the project and force a full compilation after you make changes to that specific code. This is not a new behavior. Note that you can force the compiler to always make full compilations with #DebuggerForceFullDeployment attribute.
 

OliverA

Expert
Licensed User
Longtime User
@ 2:28 AM (probably adjusted to my time zone):
@OliverA can you post the logs in debug mode, running in v9.80 and in v10.0 and also add some timing outputs? You can put a breakpoint at the end of the sub to force the debugger to use the slower execution pipeline.
68 minutes later
1. There is indeed an issue related to comparison of numbers with different types in the "rapid" execution pipeline. It is a result of a fix of a different bug (fixed a few months ago). The change will be reverted.
I'm guessing I've been Ninja'd before I could even give it a go? (btw, would not be until late Monday, about 48 hours from now)
 
Top