Announcement

Collapse
No announcement yet.

Bug in PB DLL v 6 GLOBAL/DIM?

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

  • Chris Boss
    replied
    Mike (Doty);

    The use of Globals is always a precarious thing. They are the most
    likely of variables to cause troubles. On the other hand Globals
    are a very powerful tool !

    The suggestion of using a Prefix for Globals is an 'absolute must" IMO.

    Some prefixs are ovious, like h for a handle (ie. hWnd, hCtrl, hFont, hBmp).
    They are very important for writing clean understandable code.

    Now when it comes to Globals, they are the most likely to be abused
    and can cause confusion.

    I like to use a special prefix in front of "all" my Globals, like
    App_.

    examples:

    Code:
    GLOBAL APP_Something1&
    GLOBAL APP_Something2$
    GLOBAL APP_MainhWnd&
    Now when I write a DLL, I use the prefix :

    DLL_



    ------------------

    Leave a comment:


  • Mike Doty
    replied
    Thanks Eric! (it is over a year later) and I
    found this jewel. I dimmed a string in a
    subprogram that was already a global and it
    correctly lost its value. It was definitely
    a hard one to find. I'll prefix globals
    with g_ as you suggested to avoid this.




    ------------------

    Leave a comment:


  • Guest's Avatar
    Guest replied
    While were on this subject, I'd like to suggest maybe a warning message or compile time error in trying to redim arrays contained in UDTs, after trying this weird things happened in the program and then a GPF.
    After looking at the PB5 help file
    The total size of a UDT must be known at compile time, therefore items like dynamic strings which very in size can not be part of the TYPE. A STRING PTR can..
    I figured out why, after 2 days of head scratching.

    Regards,

    Kev

    Leave a comment:


  • Guest's Avatar
    Guest replied
    What might help to prevent inadvertent mishandling of variables
    is to add a prefix to Global variable names which would distinguish
    them from the Locals: GLOBAL g_Qwerty AS ASCIIZ * 80


    Ron

    Leave a comment:


  • Don Schullian
    replied
    Hay Guys you're missing the obvious here:
    Qwerty as an ASCIIz string and Qwerty as a LONG have ALWAYS been seperate variables in BASIC!
    eg: X$, X%, X&, X! are all individual variables.
    Right?

    Leave a comment:


  • Lance Edmonds
    replied
    Peter, to help reduce the confusion when DIMming/REDIMming a global array, we recommend that you include the GLOBAL keyword in the statement: REDIM TheArray(1200) AS GLOBAL LONG

    Lance
    PowerBASIC Support

    Leave a comment:


  • Peter Manders
    replied
    I'd like to point out that the behaviour for arrays is different.
    You have to "GLOBAL TheArray() AS LONG" before your code, but can only "DIM TheArray(1000) AS LONG" inside a sub or function.
    The second one is referring to the GLOBAL array and NOT a LOCAL one.

    For the wish list:
    A compiler switch to switch on warnings about these, for debugging reasons only.

    Peter.

    Leave a comment:


  • Dave Navarro
    replied
    Michael,

    The GLOBAL isn't ignored. If you had another Sub or Function in your code where you DIDN'T also have a local variable with the same name, you would be able to interact with the global variable.

    Visual C/C++, Borland C/C++, and Delphi all allow the same type of variable scoping as PowerBASIC. It can be a *very* powerful feature if you use it correctly.

    I don't know specifically how PowerBASIC does it internally... But the way that most compilers support "locals" is to pre-append the name of the function (or Sub) in front of every local variable and label.

    So, to the compiler symbol table you would have two variables:

    QWERTY
    PBMAINQWERTY

    Every instance of a local scoped variable internally is references this way. That way, it's not possible for the compiler to accidentally use the same location in memory for variables.

    However, as I mentioned in my email to you, the C compilers and Delphi will *warn* you if you have a local variable with the same name as a global. It's strictly a warning, not an error, so it compiles anyway. PowerBASIC's not yet set up to provide warnings. It's on the wish list, though.

    --Dave

    Leave a comment:


  • Eric Pearson
    replied
    Michael --

    > It's as though the GLOBAL statment is somehow ignored as a scanned statement.

    Exactly! As I grok it, scanned statements are effectively ignored, except when they affect the compilation of other code. That's what a scanned statement is! For example, if you DIM lSomething AS LONG and then never use lSomething, it will have no effect whatsoever on the final EXE or DLL. Would you want it to? Should it trip a compile-time error?

    > Kinda shoots (...) the advantages of #DIM ALL, doesn't it?

    Not at all! You told the compiler to require you to DIM all of your variables, and it did exactly that. #DIM ALL has saved me from many, many, many problems. Saying that this "quirk" makes it worthless is... overly dramatic, in my opinion. {G}

    IMO, the paintbrush's job is to do exactly what the artist instructs it to do. I'm sure you will agree that it is up to the artist to become familiar with his tools, in order to make the best use of them. If we can't credit the paintbrush, we can't blame it either.

    Don't get me wrong... I would not mind at all if something like your #NAMECHECK ON was added to the compiler at some point in the future. Somewhere in the PowerBASIC suggestion box is an entry with my name on it, describing my wish for a $DIM STRICT option that would catch many different errors. After all, if you want the compiler to catch a local variable name that "conflicts" with a global one, why shouldn't it catch a global that is only used in one function and display and error message like "this is not a global variable, it is a static variable". And I wouldn't mind having the ability to detect those "declared but unused variables" like my lSomething example above, to keep my source code clean.

    But I've come to believe that those things -- and a long list of others -- belong in a source code proofreading program of some kind, not in the compiler itself. That's because I want a fast, efficient, two-pass compiler that does exactly what I tell it to. And if an external proofer can give me a third pass for "details" when I need it, great! My feeling is that we should let the developers at PowerBASIC concentrate on the compiler, and on the types of things that must be done in the compiler itself. There are probably a hundred different people who frequent this BBS every day who could write a very good source code proofreader! I'd rather have Bob Zale and the crew working on ActiveX/Linux/etc.

    Here's a suggestion, to help you live with the status quo... In the time since I've "moved" from DOS to Windows programming I have cultivated the habit of using "Hungarian notation" for all of my variable names. For example, glSomething would be a GLOBAL LONG variable, and ssSomething would be a STATIC STRING, and so on. Using my personal system, sSomething would be a LOCAL string... I do not usually use a prefix to denote a LOCAL scope. And every one of my DIM statements uses the 100% explicit DIM... AS GLOBAL LONG syntax. Some people turn up their nose at prefixes like that, but in my opinion they are more intuitive -- and certainly no more difficult to type -- than suffixes like $ and #.

    And after a while, seeing something like DIM gaQwerty AS LOCAL ASCIIZ will jump right out at you as an obvious error. Hungarian prefixes, properly done, make it impossible (with the exception of blatant errors, of course) to use the same variable name for a GLOBAL and for a LOCAL variable, because the scope is part of the variable name.

    -- Eric




    Leave a comment:


  • Michael Mattias
    replied
    "IMO this is not a bug unless you want to argue that, when AS GLOBAL is used, the error should be tripped on the DIM...AS LONG line instead of elsewhere."

    That's exactly what I wish to argue.

    Your answer agrees with the official answer I received, namely, that LOCAL declarations override GLOBAL declarations.

    Now this is truly weird. It's as though the GLOBAL statment is somehow ignored as a scanned statement. I have never seen this in any BASIC or COBOL compiler. (Well, I guess now I've seen it in one compiler).


    " But why do that, if the Qwerty variable is never actually used,"

    The error actually occurred in a 1000-line program. I wrote this just to see if my mind had been playing tricks on me. I was setting (what I thought) a GLOBAL variable, but it was not changing. Turns out I was changing a LOCAL same-named variable of the same type. Yes, I made an error; but the compiler did not trap it for me. Kinda shoots all to snot the advantages of #DIM ALL, doesn't it?

    Bottom line, the PB/DLL compiler does not check for name conflicts on global variables; IMO a major deficiency which should be added to the next version, probably as an option for backward compatibility, i.e,

    #NAMECHECK ON

    or something like that.

    MCM


    [This message has been edited by Michael Mattias (edited 08-20-99).]

    Leave a comment:


  • Eric Pearson
    replied
    Michael --

    The default variable type is LOCAL, so when you do this...

    Code:
    DIM Qwerty AS LONG
    ...you are saying "I want to create a LOCAL variable called Qwerty". If you change that line to...

    Code:
    DIM Qwerty AS LOCAL LONG
    ...your code still compiles. But if you do this...

    Code:
    DIM Qwerty AS GLOBAL LONG
    ...the compiler produces an error. "String Operand Expected", on the Qwerty = 2 line.

    LOCAL variable names are allowed to "conflict" with GLOBAL variable names, if that is what you tell the compiler you want to do.

    IMO this is not a bug unless you want to argue that, when AS GLOBAL is used, the error should be tripped on the DIM...AS LONG line instead of elsewhere. But why do that, if the Qwerty variable is never actually used, i.e. if the errant DIM is there but Qwerty is not actually used as a LONG. The error should be tripped when the compilation can no longer continue.

    The bottom line is that the code that you posted looks perfectly valid to me... You just left out part of the optional syntax, and the compiler used a default variable type.

    -- Eric



    [This message has been edited by Eric Pearson (edited 08-20-99).]

    Leave a comment:


  • Michael Mattias
    started a topic Bug in PB DLL v 6 GLOBAL/DIM?

    Bug in PB DLL v 6 GLOBAL/DIM?

    This is interesting enough that in addition to the note I sent to the support department, I thought I'd add it here.

    If it messed me up, it might mess up someone else, too:

    #IF 0
    ' NAME Test4.bas
    ' Demo of Bug IN compiler NOT finding GLOBALs
    8.20.99
    #ENDIF

    #COMPILE EXE
    #DIM ALL

    GLOBAL Qwerty AS ASCIIZ * 80

    FUNCTION PBMAIN()AS LONG
    DIM Qwerty AS LONG
    Qwerty = 2 '<<< Not cool for a GLOBAL ASCIIZ
    LOCAL H AS STRING
    H = "Hello World"
    MSGBOX H
    END FUNCTION

    Seems to me when I try to DIM Qwerty AS LONG inside of PBMain, I should get an error:

    466 Duplicate name definition - A SUB name, FUNCTION name, label name, or
    variable name was defined more than once in your code. Check your program
    and any include files for duplicate names and change one or both of them.

    Or am I missing something?

    MCM














Working...
X