Announcement

Collapse
No announcement yet.

Compound assignment

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

  • Compound assignment

    I've spent a few days narrowing down why my program terminates without showing me the reason.

    I found the problem with this. The last line of code was never executed.

    Code:
    TS1 += _
     SWITCH$( _
     Results_Set_Array( 1, 1 ) = "1", "Make & Model Combination Already Exists" + $CR _
     ) + _
     SWITCH$( _
     Results_Set_Array( 1, 2 ) = "1", "Make & Web Model Combination Already Exists" + $CR _
     ) + _
     SWITCH$( _
     Results_Set_Array( 1, 3 ) <> "", _
     "Barcode Already Listed With : " + PARSE$( Results_Set_Array( 1, 3 ), 1 ) + $SPC + LTRIM$( UNHEX( PARSE$( Results_Set_Array( 1, 3 ), 2 )) + $SPC + UNHEX( PARSE$( Results_Set_Array( 1, 3 ), 3 ))) + $CR _
     )
    
    TS2 = FUNCNAME$
    Code:
    FUNCTION UNHEX( S AS STRING ) common AS STRING
    '
    LOCAL TL1 AS LONG
    LOCAL NewString AS STRING
    '
    FOR TL1 = 1 TO LEN( S ) STEP 2
    '
    NewString = NewString + CHR$( VAL( "&H" + MID$( S, TL1, 2 )))
    '
    NEXT TL1
    '
    FUNCTION = NewString
    '
    END FUNCTION
    However when I change the

    TS1+=

    to

    TS1 = TS1 +

    The program continues as expected.

    in the documentation is shows x$ = x$ + y$ is identical to x$ += y$

    A compiler bug?

  • #2
    Update

    With the "TS1 += " and removing the "LTRIM$" the program doesn't crash

    Comment


    • #3
      Simplified to...
      Code:
      #COMPILE EXE
      #DIM ALL
      #INCLUDE "Win32api.inc"
      '_____________________________________________________________________________
      
      FUNCTION PBMAIN () AS LONG
       LOCAL sString AS STRING
      
       sString = "Testing the build of a string - "
       sString = sString + "a" + SWITCH$("x" <> "y", "" + LTRIM$("" + PARSE$("44", 1)))
       MSGBOX sString, , "sString = sString &... - No GPF"
      
       sString = "Testing the build of a string - "
       sString += "a" + SWITCH$("x" <> "y", "" + LTRIM$("" + PARSE$("44", 1)))
       MSGBOX sString, , "sString +=... will GPF"
      
      END FUNCTION
      '_____________________________________________________________________________
      '

      Comment


      • #4
        [code]
        FUNCTION PBMAIN () AS LONG
        LOCAL sString AS STRING

        sString = "Testing the build of a string - "
        sString = sString + "a" + SWITCH$("x" <> "y", "" + LTRIM$("" + PARSE$("44", 1)))
        MSGBOX sString, , "sString = sString &... - No GPF"

        sString = "Testing the build of a string - "
        sString += "a" + SWITCH$("x" <> "y", "" + LTRIM$("" + PARSE$("44", 1)))
        MSGBOX sString, , "sString +=... will GPF"
        msgbox "OK"
        msgbox FUNCNAME$
        msgbox "OK"
        END FUNCTION
        [code]

        The 1st OK is executed but calling FUNCNAME$ causes the crash and the second "OK" isn't executed.

        Comment


        • #5
          It appears FUNCNAME$ does not work in PBMAIN(). Now goes to end -
          Code:
          #compile exe
          #dim all
          
          function pbmain () as long
            local sString, x as string
          
            sString = "Testing the build of a string - "
            sString = sString + "a" + switch$("x" <> "y", "" + ltrim$("" + parse$("44", 1)))
            msgbox sString, , "sString = sString &... - No GPF"
          
            sString = "Testing the build of a string - "
            sString += "a" + switch$("x" <> "y", "" + ltrim$("" + parse$("44", 1)))
            msgbox sString, , "sString +=... will GPF"
            msgbox "OK1"
          '  x = FUNCNAME$ 'tried going via string first, didn't help
          '  msgbox x
            TryFuncname   'added SUB call, where SUB contains FUNCNAME$
            msgbox "OK2"
          end function
          sub TryFuncname()
            local x as string
            x = funcname$
            msgbox x
          end sub
          (have a hunch that I'll keep to myself)

          Cheers,
          Dale

          Comment


          • #6
            It has nothing to do with "FUNCNAME$". As per documentation you cannot have an EXPRESSION in place of a VALUE with "SWITCH$"

            Code:
             
             ...   
             "Barcode Already Listed With : " + PARSE$( Results_Set_Array( 1, 3 ), 1 ) + $SPC + LTRIM$( UNHEX( PARSE$( Results_Set_Array( 1, 3 ), 2 )) + $SPC + UNHEX( PARSE$( Results_Set_Array( 1, 3 ), 3 ))) + $CR
            is an expression (a quite complex one)!


            You might get away with a more simple expression (string concatenation), but f it get´s too complex it will crash. So in my view not a bug but incorrect (because unsupported) syntax.


            JK

            Comment


            • #7
              I'll go along with FUNCNAME$ having nothing to do with the original problem. I was responding to post #4 where the line of code you show does not even exist!

              (another copy of remedial reading for the champ in post #6)
              Dale

              Comment


              • #8
                pbDoc: var$ = SWITCH$(expr1, val1$ [[, expr2, val2$], ...])

                pbDoc: The value parameters may be expressions, literals or variables...

                Juergen, may you elaborate a little on the following? you cannot have an EXPRESSION in place of a VALUE with "SWITCH$"

                Can I say that From your perspective the following is illegal...
                MSGBOX SWITCH$(1 = 1, TRIM$(" 123 ") & TRIM$(" 456 ")), , "SWITCH$"

                Comment


                • #9
                  Pierre,

                  my bad, i missed the word "expressions" in "The value parameters may be expressions, literals or variables of the appropriate data type ...", so my conclusion was wrong!

                  Playing around with the posted code i never get crashes, when the value parameter is a value, but i get crashes for certain kinds of expressions (e.g code of post #3) - in fact this seems to be a bug then.


                  Dale,

                  It appears FUNCNAME$ does not work in PBMAIN(). Now goes to end -
                  Code:
                  FUNCTION PBMAIN () AS LONG
                  
                    MSGBOX FUNCNAME$
                  
                  END FUNCTION

                  JK

                  Comment


                  • #10
                    Code:
                    #compile exe
                    #dim all
                    
                    function pbmain () as long
                      local sString, x as string
                    
                      sString = "Testing the build of a string - "
                      sString = sString + "a" + switch$("x" <> "y", "" + ltrim$("" + parse$("44", 1)))
                      msgbox sString, , "sString = sString &... - No GPF"
                    
                      sString = "Testing the build of a string - "
                      sString += "a" + switch$("x" <> "y", "" + ltrim$("" + parse$("44", 1)))
                      msgbox sString, , "sString +=... will GPF"
                      msgbox "OK1"
                      msgbox funcname$
                      msgbox "OK2"
                    end function
                    Still does not show the "PBMain" megbox, nor "OK2" msgbox here. Whether your slightly different code works for you I do not care. I tested what Steve said and found what he said to be happening.
                    Dale

                    Comment


                    • #11
                      Steve,

                      You can use CallStk$(1) in place of FUNCNAME$ and then the second "OK" is executed

                      Not really useful though as the GPF still occurs after the second "OK"

                      The sString += .. line does not seem to cause a problem if written like this
                      Code:
                      sString += "a" + SWITCH$("x" <> "y", "" + "" + LTRIM$(parse$("44", 1)))
                      But that doesn't explain why using the operator shortcut ' += ' behaves differently
                      Rgds, Dave

                      Comment


                      • #12
                        Well, investigating this issue a bit further, it seems it isn´t related to "SWITCH$". This is what i tested:

                        Code:
                        #COMPILE EXE
                        #DIM ALL
                        #INCLUDE "Win32api.inc"
                        
                        
                        FUNCTION PBMAIN () AS LONG
                        '***********************************************************************************************
                        ' main
                        '***********************************************************************************************
                        LOCAL s AS STRING
                        local d as string
                        
                        
                          d = "44"
                        
                        
                        '  s += "a" + "4"                                      'ok
                        '  s += "a" + "" + LTRIM$("" + PARSE$("44", 1))        'ok
                        '  s += SWITCH$("x" <> "y", "" + LTRIM$("" + PARSE$("44", 1)))             'ok
                        '                                                      
                        '  s += "a" + SWITCH$("x" <> "y", "" + LTRIM$("" + PARSE$("44", 1)))       'gpf
                        '  s += "a" + SWITCH$("x" <> "y", "b" + LTRIM$("" + PARSE$("44", 1)))      'gpf
                        '  s += "a" + SWITCH$("x" <> "y", "b" + LTRIM$("c" + PARSE$("44", 1)))     'gpf
                        '  s += "a" + SWITCH$("x" <> "y", "b" + LTRIM$("c" + PARSE$("44", 1)))     'gpf
                        '  s += "a" + SWITCH$("x" <> "y", "b" + LTRIM$(" c" + PARSE$("44", 1)))    'gpf
                        '  s += "a" + SWITCH$("x" <> "y", "b" + TRIM$(" c" + PARSE$("44", 1)))     'gpf
                        '  s += "a" + SWITCH$("x" <> "y", "b" + ucase$(" c" + PARSE$("44", 1)))    'gpf
                        '
                        '  s += "a" + lcase$("b" + ucase$(" c" + lcase$("d"))) 'ok
                        '  s += "a" + lcase$("b" + ucase$(" c" + trim$("d")))  'ok
                        '
                        '  s += "a" + lcase$("b" + ucase$(" c" + trim$(d)))    'ok
                        '  s += "a" + ucase$("b" + ucase$(" c" + space$(5)))   'ok
                        '
                        '  s += "a" + ucase$("b" + ucase$(" c" + remove$(d, "4")))                 'gpf
                        '  s += "a" + ucase$("b" + ucase$(" c" + shrink$(d)))                      'gpf
                        '  s += "a" + ucase$("b" + ucase$(" c" + shrink$(" 44")))                  'gpf
                        '  s += "a" + ucase$("b" + ucase$(shrink$(" 44")))                         'ok
                        '  s += "a" + ucase$("b" + ucase$("c" + shrink$(" 44")))                   'gpf
                        '  s += "a" + ucase$("b" + ucase$("c" + left$(" 44", 1)))                  'ok
                        '  s += "a" + ucase$("b" + ucase$("c" + right$(" 44", 1)))                 'ok
                        '  s += "a" + ucase$("b" + ucase$("c" + mid$(" 44", 2, 1)))                'ok
                        '
                        '  s += "a" + ucase$("b" + extract$(" c" + trim$(d), "4"))                 'ok
                        '  s += "a" + ucase$("b" + parse$(" c" + ucase$(d), 1))                    'ok
                        '
                          s += "a" + ucase$("b" + trim$(" c" + extract$(d, "4")))                 'gpf
                        '  s += "a" + ucase$("b" + ucase$(" c" + extract$(d, "4")))                'gpf
                        '  s += "a" + ucase$("b" + ucase$(" c" + PARSE$(d, 2)))                    'gpf
                        '  s += "a" + ucase$("b" + ucase$(" c" + PARSE$(d, 1)))                    'gpf
                        '
                        '  s += "a" + ucase$("b" + ucase$(" c" + PARSE$("44", 1)))                 'gpf
                        '  s += "a" + lcase$("b" + ucase$(" c" + PARSE$("44", 1)))                 'gpf
                        '
                        '  s += "a" + lcase$(ucase$(" c" + PARSE$("44", 1)))   'ok
                        '  s += "a" + lcase$("b" + ucase$(PARSE$("44", 1)))    'ok
                        '
                        '  s = s + "a" + SWITCH$("x" <> "y", "b" + ucase$(" c" + PARSE$("44", 1))) 'ok
                        '  s += "a" + SWITCH$("x" <> "y", "b" + ucase$(PARSE$("44", 1)))           'ok
                        '  s += "a" + SWITCH$("x" <> "y", "b" + "c" + PARSE$("44", 1))             'ok
                        '  s += "a" + SWITCH$("x" <> "y", "b" + LTRIM$(PARSE$("44", 1)))           'ok
                        '  s += "a" + SWITCH$("x" <> "y", LTRIM$("" + PARSE$("44", 1)))            'ok
                        '  s += SWITCH$("x" <> "y", "Barcode Already Listed With : " + LTRIM$("" + PARSE$("44", 1))) 'ok
                        
                        
                        ods(s)                                                'outputdebugstring
                          s = "Test"
                        ods(s)                                                'outputdebugstring
                        
                        
                        END FUNCTION                                          '-> gpf here, if any

                        As you can see, it will gpf with "EXTRACT$" and some others too. "SWITCH$" is not necessary for a GPF. Conditions for a GPF are:
                        - compound assignment ("+=")
                        - at least three nested string handling statements in combination with a string concatenation
                        - the last (rightmost) string function low level wise creates an intermediate string (parse, shrink, extract, remove)

                        The resulting string ("s") is created properly, but afterwards to me it looks like there is a serious problem with the "cleanup" code for the intermediate string.


                        JK

                        Comment


                        • #13
                          Glad it's not me then. TBH I only read up on the compound statements recently so did a find and replace on my code.

                          Might just put it all back as it was.

                          Comment


                          • #14
                            Finally, in regard to string, the internal line parser of the compiler could be more robust.
                            sString = sString + ... and sString += ... should give the same result and it don't.
                            I guess that keeping it real simple is the rule to avoid potential problem.

                            On the other hand, with numeric, I was unable to get a GPF, wich is good news...
                            Code:
                            n += 1 + PEEK(DWORD, VARPTR(n)) + SWITCH(1 <> 2, 3 + ASC("A") + VAL("&h44")) + _ 'n = 137
                                 FRAC(MAKDWD((ABS(123.45 AND 33) OR 789) + BIT(n, 31), CINT(CHOOSE&(1, 0, 1, 2))))

                            Comment


                            • #15
                              Nice job of nailing the issue! Thanks. This 'feature' should be added to the online help, I don't have time at the moment. Maybe later.
                              ]
                              Rod
                              "To every unsung hero in the universe
                              To those who roam the skies and those who roam the earth
                              To all good men of reason may they never thirst " - from "Heaven Help the Devil" by G. Lightfoot

                              Comment

                              Working...
                              X