Announcement

Collapse
No announcement yet.

Problems, Questions, Suggestions

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Problems, Questions, Suggestions

    Using 486dx33 8MB and 386sx20 6MB with QEMM 8.0, PB/DOS 3.5

    Let's start with my problem... I always use the IDE to edit, compile and debug my programs. That's
    just the way I prefer to work. But now this debugging problem really starts annoying me. Could anyone
    explain me what '????' means when evaluating or watching a variable (within its scope)...? Could it
    be a memory problem, or is the PB IDE just not always capable of displaying the value. It's really
    weird that when I run the program step by step (F7), a watch variable suddenly turns to '????' while
    it's still in the same SUB or FUNCTION... It doesn't matter whether I use PB.EXE or PBD.EXE to run
    my program, with or without the $DEBUG PBDEBUG/UNIT/MAP lines.
    Please help me, how should I debug my program? And what's the use of the MAP file?

    A problem that I cannot reproduce on command: when compiling a program in the IDE I often get errors like:
    Error xx: Missing declaration:
    Note that the smiley (CHR$(1)) really shows up in the error line. It should display a variable name instead.

    When executing a STDOUT "Boo!" command with F7, the text is printed to the editor screen
    instead of to the user screen (with Smart display swapping). Is this correct behaviour?

    The compiler refuses to display an error message, where in my opinion it should do.
    Problems could occur in the following situation:
    Code:
    $DIM ALL
    DECLARE MySub()
    DIM MyVar AS SHARED INTEGER
    
    MyVar = 1
    CALL MySub()
    PRINT MyVar
    
    SUB MySub()
        DIM MyVar AS INTEGER
        MyVar = -1
    END SUB
    One could think that a local variable MyVar was created in the SUB, or otherwise at least an error
    message like "duplicate definition" was displayed... neither is true... It seems that the DIM statement
    in the SUB is ignored since there is already a global variable with the same name. I know of the
    use of the LOCAL keyword which should have been used in the SUB. But still, it puzzles me why
    the compiler doesn't warn me about this.

    Have a look at the following two fragments of code:
    Code:
    SUB putpixel1 (BYVAL x AS INTEGER, BYVAL y AS INTEGER, BYVAL c AS BYTE)
        SELECT CASE graph_mode
            CASE %GRAPH320x200
                DEF SEG = &HA000
                POKE x + y*320, c
                DEF SEG
            CASE %GRAPH640x480
                PSET(x, y), c
        END SELECT
    END SUB
    
    SUB putpixel2 (BYVAL x AS INTEGER, BYVAL y AS INTEGER, BYVAL c AS BYTE)
        IF graph_mode = %GRAPH320x200 THEN
            DEF SEG = &HA000
            POKE x + y*320, c
            DEF SEG
        ELSEIF graph_mode = %GRAPH640x480 THEN
            PSET(x, y), c
        END IF
    END SUB
    The difference between the two routines is enormous when looking at the execution speed. The IF/ELSE
    method is 4-5 times faster than the SELECT CASE method. What's also remarkable is that the execution
    speed of the SELECT CASE method depends on the test value (in this case 'graph_mode'). For example:
    Code:
    SUB test (BYVAL method AS INTEGER)
        SELECT CASE method
        CASE 0: PRINT "Just a string"
        CASE 1: PRINT "Just a string"
        CASE 2: PRINT "Just a string"
        END SELECT
    END SUB
    This routine would execute faster if method=0 than if method=1 or 2, but still much slower than when an
    IF statement would have been used. What is the advantage of using SELECT CASE ?
    I'm considering writing yet another preprocessor that replaces all SELECT CASE blocks with IF/ELSE blocks.

    Ok, then another fragment that results in a run-time error:
    Code:
    $DIM ALL
    $ERROR ALL ON
    
    DIM test_array(1 TO 10) AS BYTE
    DIM element AS INTEGER
    
    element = 0
    
    IF (element > 0) AND (test_array(element) > 0) THEN
        PRINT test_array(element)
    END IF
    It would be much more efficient if the second expression on the IF line was never tested, because the
    entire condition could never become TRUE anymore. I don't like comparing to PB to C++, but in this case C++
    already has this efficiency... Just imagine the following piece:
    Code:
    IF (  0=1  ) AND _
       ( (1=1) OR (2=2) OR (3=3) OR (4=4) OR (5=5) OR (6=6) OR (7=7) OR (8=8) ) THEN
    
    END IF
    After testing 0=1 which is FALSE, all of the following expressions are tested needlessly. If this could be
    prevented, it would not only increase speed of the program, but also result in cleaner code (in my opinion)...
    The first example needs to be changed to:
    Code:
    IF (elements > 0) THEN
        IF (test_array(element) > 0) THEN
            PRINT test_array(element)
        END IF
    END IF
    Hmm, I think that's about it. I hope some of you can answer my questions, and respond to other points made

    Regards,

    ------------------
    Sebastian Groeneveld
    mailto:[email protected][email protected]</A>
    Sebastian Groeneveld
    mailto:[email protected][email protected]</A>

  • #2
    These sound very much like classic "memory manager" problems.

    1st, try disabling QEMM, or at least ensure that "Stealth" mode is disabled...

    Do you have the very latest version of QEMM? Patches?

    Also, try disabling XMS and EMS with PBINST.

    Also, you could try using EMM386 that came with DOS 6.2x, or if all else fails, the one that came with Windows.

    Please let us know how you get on.

    ------------------
    Lance
    PowerBASIC Support
    mailto:[email protected][email protected]</A>
    Lance
    mailto:[email protected]

    Comment


    • #3
      More:

      1. The duplicate variable error will not occur if you include the word LOCAL in the DIM statement in the SUB... otherwise the compiler assumes that you are just redeclaring the same variable... ie:
      Code:
      $DIM ALL
      DIM MyVar AS SHARED INTEGER
      MyVar = 1
      CALL MySub()
      PRINT MyVar
      
      SUB MySub()
              DIM MyVar AS [b][i]LOCAL[/i][/b] INTEGER
              MyVar = -1
      END SUB
      2. SELECT CASE can be slower as it has convert numerics to extended precision in order to fulfill the possible matches in each CASE statement. Conversely, IF THEN statements can be optimized on a per-statement basis.

      3. By enclosing your IF THEN expressions in parentheses, you are telling PB to do bit-wise evaluations, rather than short-circuit evaluations (where the 2nd expressions test would not be performed)... this is discussed in the documentation!

      I hope this helps!


      ------------------
      Lance
      PowerBASIC Support
      mailto:[email protected][email protected]</A>
      Lance
      mailto:[email protected]

      Comment


      • #4
        Hi all,

        I thought I'd better put this in an existing thread, instead of creating a new one
        for this minor problem... Besides this problem also concerns Watch/Evaluate...
        Code:
        TYPE UserType
            UserArray(1 TO 10) AS INTEGER
        END TYPE
        
        DIM MyArray(1 TO 10) AS UserType
        Now I cannot watch or evaluate the following line (Ctrl+F4 or Ctrl+F7)
        MyArray(1).UserArray(1)

        The cursor is positioned at the first closing bracket. I'm quite sure this is not an
        EMS manager error.
        As you guess I'm using lots of variables that contain arrays in the UDT, and I would
        love to be able to see them while debugging... Even better, it would be great if there
        was an Immediate window, in which it's possible to PRINT all kinds of PB functions,
        like CURDIR$ or SQR or MOD...

        Greetings,

        ------------------
        Sebastian Groeneveld
        mailto:[email protected][email protected]</A>
        Sebastian Groeneveld
        mailto:[email protected][email protected]</A>

        Comment

        Working...
        X