Announcement

Collapse
No announcement yet.

Conditional confusion

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

  • Conditional confusion

    I reckon I've been doing this for long enough, at over 30 years, but forgive me if I've got something terribly wrong!

    For conditional compilation "#if %equate = 0" is meant to work the same as "#if not %equate", isn't it? According to the manual it does, and according to what one would expect from other languages.

    Well, it may be that you get the correct logic blocks executing, so the program runs correctly, but the output sure as anything is different! For example, I have some DLLs which I can compile with a %testing equate set so they can be stand-alone executables for debugging. That's been fine, for years. But just now I was surprised to see a load of string literals in the output binary code of the release DLL version which occur ONLY in the stand-alone debug sections of the source. Sure enough, if I recompiled with "#if %testing = 0" rather than "#if not %testing", I got the correct output, and the executable was over 2k smaller in a 94k program.

    Now that shouldn't be happening, should it?

    The terrible thing about this is that I have circulated what should be "clean" release versions which contain visible data strings of security keys from the other sections ...

    It's the same whether in PBWin8 or PBWin9. I haven't checked PBCC yet, but I bet it's the same as PBWin.

    Any comments?

    Andrew Parker.

  • #2
    Since you haven't shown any code which demonstrates this occurring, it's virtually impossible for anyone to offer a meaningful suggestion. Make a sample and show some code?

    I don't suppose you're using the intrinsic equate %PB_EXE, are you? We have advised that it should not be used in PB/WIN 9.00 for some time now: http://powerbasic.com/support/pbforu...ad.php?t=38661

    Best regards,

    Bob Zale
    PowerBASIC Inc.

    Comment


    • #3
      FWIW, be VERY careful using NOT in your conditional compilation statements, except perhaps when used with %DEF().

      Why? Because "NOT 1" does not equal "zero."

      MCM
      Michael Mattias
      Tal Systems (retired)
      Port Washington WI USA
      [email protected]
      http://www.talsystems.com

      Comment


      • #4
        NOT returns results not expected

        Originally posted by Andrew Parker View Post

        For conditional compilation "#if %equate = 0" is meant to work the same as "#if not %equate", isn't it? According to the manual it does, and according to what one would expect from other languages.

        Well, it may be that you get the correct logic blocks executing, so the program runs correctly, but the output sure as anything is different! For example, I have some DLLs which I can compile with a %testing equate set so they can be stand-alone executables for debugging. That's been fine, for years. But just now I was surprised to see a load of string literals in the output binary code of the release DLL version which occur ONLY in the stand-alone debug sections of the source. Sure enough, if I recompiled with "#if %testing = 0" rather than "#if not %testing", I got the correct output, and the executable was over 2k smaller in a 94k program.

        Now that shouldn't be happening, should it?

        Any comments?

        Andrew Parker.
        Read the help file on NOT keyword. Some info from the help file is below.

        NOT is a bitwise arithmetic operator and is often incorrectly used as a Boolean operator. Use IsFalse instead.

        Not -1 = 0
        Not 0 = -1
        Not 1 = -2 (canPrint was set to 1)

        NOT returns 0 (FALSE) if and only if its operand is exactly -1 (TRUE).

        Generally, you should use the ISFALSE operator instead of NOT, when you are testing for logical falsity.

        I've made this mistake myself and still do when I forget. Bugs me every time I do it too.

        Comment


        • #5
          I've made some samples, and confirmed that it's happening ...

          But I've also confirmed why it is happening, and Michael and Brian are quite right. There's no point in me posting my results

          But I have to say the help file on #IF is very misleading. It shows signs of having been put together at different times! True, it states that the NOT operator is bitwise arithmetic, but it also contains this:

          Examples of valid expressions can include:

          #IF %DEBUG = -1&
          #IF %DEBUG AND (NOT %RELEASE)
          #IF NOT %DEBUG
          #IF %VERSION <> CVQ("DemoMode")

          Note that the AND, OR and NOT operators work as bitwise operators, rather than logical operators, in #IF metastatements.

          If the value of %equate or if %DEF(%equate|$equate) is TRUE (non-zero) or if the result of expression is TRUE, the statements between #IF and #ELSE or #ELSEIF are compiled, and the statements between #ELSE or #ELSEIF and #ENDIF are ignored.

          If the value of %equate or %DEF(%equate|$equate) is FALSE (zero) or the result of expression is FALSE, the statements between #IF and #ELSE or #ELSEIF are ignored, and those between #ELSE or #ELSEIF and #ENDIF are compiled.
          I've hilighted the misleading sections. They are misleading particularly when you give "#IF NOT %DEBUG" as a valid statement. Yes, it's valid, but it won't function as you might logically expect if you combine that information with the statements in the next two paragraphs! The point is that you are quoiting TRUE and FALSE, but the evaluation is not taking place that way. It will work in that manner only if -1 is selected as the TRUE condition and 0 as the FALSE one.

          When conditional compilation is often a logical choice between one condition or another, can anyone tell me why bitwise arithmetic was deemed the way to evaluate #IF statements?

          Andrew Parker

          Comment


          • #6
            Let's see...

            TRUE = Non-Zero and FALSE = Zero

            These are misleading? What about them is misleading? What is the real definition of True and False?

            "...can anyone tell me why bitwise arithmetic was deemed the way to evaluate #IF statements?"

            I may be wrong here, but it looks to me like you were the one who made the choice to use a bitwise operator. A boolean expression returns a boolean result. You can use any number of numeric operators and any number of numeric operands when forming it. All those choices were yours. This just needs a little more practice. {smile}

            Best of luck,

            Bob Zale
            PowerBASIC Inc.

            Comment


            • #7
              Hi Andrew:

              can anyone tell me why bitwise arithmetic was deemed the way to evaluate #IF statements?
              I think you did, "#IF %DEBUG = -1&" is not a bitwise operation.

              Note that the AND, OR and NOT operators work as bitwise operators, rather than logical operators, in #IF metastatements.
              By including the "NOT" in "#IF NOT %DEBUG" you make it a bitwise operation, as stated in the manual.
              Regards,
              Marc

              Comment


              • #8
                Oh for goodness sake.

                I was quoting the help file when I quoted "#IF %DEBUG = -1&", so telling me I just answered my question is pretty unhelpful.

                As for Mr Zale's rather aggressive response, telling me that it's been my choice, and, in effect, I should learn to live with it and I just need a little more practice:

                It's your helpfile which introduces the idea of combining the bitwise operator with the logical expression. I suggest you seriously consider whether giving "#IF NOT %DEBUG" as an example of a valid syntax isn't encouraging people to use it in the way it won't work.

                Asking me about the real meaning of TRUE and FALSE I find rather offensive.

                I think you're on the brink of losing a customer.

                Andrew Parker.

                Comment


                • #9
                  "IF NOT %DEBUG" returns the desired result (false) if an only if %DEBUG equals precisely -1& (minus one) - as shown but not explained.

                  But you are right, it is a crummy example. Don't do that, or some day it WILL bite you in a tender place.
                  Michael Mattias
                  Tal Systems (retired)
                  Port Washington WI USA
                  [email protected]
                  http://www.talsystems.com

                  Comment


                  • #10
                    Originally posted by Andrew Parker View Post
                    Oh for goodness sake.

                    #IF NOT %DEBUG
                    Code:
                    #IF %DEBUG = -1& ' <- does the %DEBUG equate equal -1?
                    #IF %DEBUG AND (NOT %RELEASE) ' <- IF %DEBUG is defined and %RELEASE is not defined
                    
                     #IF NOT %DEBUG ' <- IF %DEBUG is not definded
                    
                     #IF %VERSION <> CVQ("DemoMode")
                    As I read them.


                    Did not put anything with the last one because, of the CVQ function, am going to have to experiment with that sucker. The documentation sez:
                    Expressions involving Numeric Equates and conditional compilation (#IF) may also include the CVQ function. This allows you to easily assign numeric values to an equate, based upon a meaningful mnemonic. In this context, the CVQ expression is limited to a length of eight bytes.
                    My brain went flip flop over this, interesting.
                    Furcadia, an interesting online MMORPG in which you can create and program your own content.

                    Comment


                    • #11
                      #IF NOT %DEBUG ' <- IF %DEBUG is not definded
                      If you use #IF NOT %DEBUG, and %DEBUG is not defined, you will get an Undefined equate error. You must use #IF NOT %DEF(%DEBUG).
                      Forum: http://www.jose.it-berater.org/smfforum/index.php

                      Comment


                      • #12
                        #IF %DEBUG AND (NOT %RELEASE) ' <- IF %DEBUG is defined and %RELEASE is not defined
                        This statement tests values, not if the equates have been defined or not.

                        %DEF() is used to determine if an equate has been defined.
                        Michael Mattias
                        Tal Systems (retired)
                        Port Washington WI USA
                        [email protected]
                        http://www.talsystems.com

                        Comment


                        • #13
                          Ahh, thank you, and another light bulb gets lit for me.
                          Furcadia, an interesting online MMORPG in which you can create and program your own content.

                          Comment


                          • #14
                            I just think it's a couple of paragraphs or three of the helpfile which could be more transparently written, or attention could be drawn as to what #IF NOT %DEBUG really means.

                            Perhaps if the debugger was able to show the evaluation of conditional compilation switches it would be an easy way of people no longer falling into these traps? Perhaps it could render the lines in the source code which will not be compiled in gray? Furthermore it would be good if it could also avoid stepping through each of the lines, regardless of their compilational status, and just jumping over a section which is inoperative?

                            Andrew Parker.

                            Comment


                            • #15
                              The following mini-tutorial on Logical True and False values may help. It applies to conditional compilation and everything else.

                              http://www.powerbasic.com/support/pb...73&postcount=9

                              Colin --

                              The coolest thing (IMO) about using the CVQ function to create equates is that your program can then simply display them, using the MKQ$ function. For example if you use %PROGRAM_MODE = CVQ("DemoMode") then your program can display MKQ$(%PROGRAM_MODE) and you'll see "DemoMode". The basic idea is a number that works like a number and a human-readable string at the same time.

                              -- Eric
                              "Not my circus, not my monkeys."

                              Comment


                              • #16
                                Andrew,
                                I feel your pain as far as documentation, (MSDN is WAYYYY worse though)

                                Bob may have sounded a little brisque with
                                Let's see...

                                TRUE = Non-Zero and FALSE = Zero

                                These are misleading? What about them is misleading? What is the real definition of True and False?
                                But I am sure it was not meant that way....it was more a lead to what we all often forget is...."What is TRUE" and "What is FALSE" ????

                                A common case in point would be PB usually refers to "True" to be 1, and "False" to be 0, API on the other hand tends to lend to "True" to be either 1 or -1 (or some other NON-ZERO value

                                but we forget the meaning that TRUE (as documented) means "Any Non zero value)

                                Now in the scope of what you are trying to do.....usually no problems, but when problems arise, its awfully hard to find because you take an assumption and think of true=1 false = 0


                                95-5 rule.....95% of examples cover all examples, 5% "break" them....and if you hit the 5%...then back to "basics" of if the example "Fits" your problem????

                                Engineer's Motto: If it aint broke take it apart and fix it

                                "If at 1st you don't succeed... call it version 1.0"

                                "Half of Programming is coding"....."The other 90% is DEBUGGING"

                                "Document my code????" .... "WHYYY??? do you think they call it CODE? "

                                Comment


                                • #17
                                  Originally posted by Eric Pearson View Post
                                  The coolest thing (IMO) about using the CVQ function to create equates is that your program can then simply display them, using the MKQ$ function. For example if you use %PROGRAM_MODE = CVQ("DemoMode") then your program can display MKQ$(%PROGRAM_MODE) and you'll see "DemoMode". The basic idea is a number that works like a number and a human-readable string at the same time.
                                  Oh! Sort of like using:
                                  Code:
                                  TYPE BITMAPFILEHEADER WORD
                                    bfType AS STRING * 2
                                    bfSize AS DWORD
                                    bfReserved1 AS WORD
                                    bfReserved2 AS WORD
                                    bfOffBits AS DWORD
                                  END TYPE
                                  Instead of:
                                  Code:
                                  TYPE BITMAPFILEHEADER WORD
                                    bfType AS WORD
                                    bfSize AS DWORD
                                    bfReserved1 AS WORD
                                    bfReserved2 AS WORD
                                    bfOffBits AS DWORD
                                  END TYPE
                                  So that in the program, you can use the simple test of:
                                  Code:
                                  IF fileBitmapHead.bfType = "BM" THEN
                                  Furcadia, an interesting online MMORPG in which you can create and program your own content.

                                  Comment


                                  • #18
                                    Thanks for that Colin.

                                    Originally posted by Cliff Nichols View Post
                                    I feel your pain as far as documentation, (MSDN is WAYYYY worse though)
                                    I know only too well ...

                                    A common case in point would be PB usually refers to "True" to be 1, and "False" to be 0, API on the other hand tends to lend to "True" to be either 1 or -1 (or some other NON-ZERO value
                                    I've got a feeling that, in the old days, PB for DOS used -1 for TRUE (I suppose because NOT TRUE would give 0). Yes, the confusion is at its height when TRUE = 1 and NOT TRUE therefore = -2.

                                    I'm still quite keen on the idea of the debugger responding to conditional switches in compilation by rendering the "switched off" sections of code in gray ... I reckon if people had a quick visual reassurance of what was about to happen in that way, it would be the end to all confusion. Well, gray display, and not still stepping line by line through those inoperative sections, which is what happens stepwise in the debugger now!

                                    Comment


                                    • #19
                                      I'm afraid that's misinformation. Every version of PowerBASIC has returned -1 for TRUE and 0 for FALSE. There has never been an exception to this rule, and we do not expect one in the future. This philosophy has been followed by virtually all credible versions of the BASIC programming language

                                      When PowerBASIC evaluates a Boolean expression, it treats the result as any non-zero value as true and zero as false. This philosophy is followed by virtually all programming languages.

                                      The Windows API generally returns the value one (1) for TRUE and zero (0) for false. For that reason, it was necessary to identify the equate %true = 1 in the WIN32API.INC header file. However, please note that both true values are evaluated properly as the result of a Boolean expression.

                                      Best regards,

                                      Bob Zale
                                      PowerBASIC Inc.

                                      Comment


                                      • #20
                                        Never test a function which returns 'true' or 'false' (most Windows' API functions return 'true' or 'false' ) for equality with an artificial constant such as %TRUE or even minus-one.

                                        This is why ISTRUE() and ISFALSE() exist.

                                        If your code is written properly, you could define....
                                        Code:
                                        %TRUE =  66872
                                        ... and your program would still work perfectly.
                                        Michael Mattias
                                        Tal Systems (retired)
                                        Port Washington WI USA
                                        [email protected]
                                        http://www.talsystems.com

                                        Comment

                                        Working...
                                        X