Jump to content

SciTE warning if global variable defined inside function


LoWang
 Share

Recommended Posts

f1()
msgbox(0,"",$v)

func f1()
global $v
$v=1
EndFunc

This causes SciTE to say WARNING: $v: possibly used before declaration.

Is this necessary? I think it is a bug. And please before you bash me with your advices about code writing rules and such things and tell me I have to declare all variables at the script beginning:) think about it - I have a lot of functions in an include file and I don't really need to have my memory eaten by declaring variables which I don't always use. I want to call my function and have it declare all necessary variables which may or may not be used in a script in which I use that function. That's why I have the "global" statement in my functions to avoid error if the var is not used in a script which calls it. What do you say?

Link to comment
Share on other sites

  • Moderators

LoWang,

It is not a bug. You can prevent it happening by not setting the -w 4 parameter for Au3Check when adding the #AutoIt3Wrapper_au3check_parameters= directive to the top of your script. The AutoIt3Wrapper default is -d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 - you just need to remove the -w 4. :x

Usage: Au3Check [-q] [-d] [-u file] [-w[-] n].. [-v[-] n].. [-I dir].. file.au3
            -q      : quiet (only error/warn output)
            -d      : as Opt("MustDeclareVars", 1)
            -I dir  : additional directories for searching include files
            -U -|file : output unreferenced UDFs and global variables
            -w 1      : already included file (on)
            -w 2      : missing #comments-end (on)
            -w 3      : already declared var (off)
            -w 4      : local var used in global scope (off)
            -w 5      : local var declared but not used (off)
            -w 6      : warn when using Dim (off)
            -v 1      : show include paths/files (off)
            -v 2      : show lexer tokens (off)

As to using memory that you do not need, you only need to use the /StripOnly parameter with Obfuscator and all your unused functions and variables are removed automatically. :shifty:

So you can declare your Global variables at the top of your script which experience has shown is the best practice - which is not bashing you, just stating a fact. :P

M23

Public_Domain.png.2d871819fcb9957cf44f4514551a2935.png Any of my own code posted anywhere on the forum is available for use by others without any restriction of any kind

Open spoiler to see my UDFs:

Spoiler

ArrayMultiColSort ---- Sort arrays on multiple columns
ChooseFileFolder ---- Single and multiple selections from specified path treeview listing
Date_Time_Convert -- Easily convert date/time formats, including the language used
ExtMsgBox --------- A highly customisable replacement for MsgBox
GUIExtender -------- Extend and retract multiple sections within a GUI
GUIFrame ---------- Subdivide GUIs into many adjustable frames
GUIListViewEx ------- Insert, delete, move, drag, sort, edit and colour ListView items
GUITreeViewEx ------ Check/clear parent and child checkboxes in a TreeView
Marquee ----------- Scrolling tickertape GUIs
NoFocusLines ------- Remove the dotted focus lines from buttons, sliders, radios and checkboxes
Notify ------------- Small notifications on the edge of the display
Scrollbars ----------Automatically sized scrollbars with a single command
StringSize ---------- Automatically size controls to fit text
Toast -------------- Small GUIs which pop out of the notification area

 

Link to comment
Share on other sites

How is the computer supposed to know? Let's look at this code:

Call("_Declare")
MsgBox(0, "Test", $v)

Func _Declare()
    Global $v = 42
EndFunc

There is absolutely no way in which the computer can tell before running that $v will be declared. There is also the chance that it isn't declared at all, when you think it is. A few extra globals are not going to make a difference anyway.

Just turn it off if it bugs you :x

Link to comment
Share on other sites

So you're making a single use function, what's the point of making such a function? By using a global in the function if you wish to reuse the function, you'll be resetting the global var every time?

I believe there is another thread going on where someone is being stubborn about such uses of global vars in functions heh.

Your scope in a function should end at the end of a function, AutoIt offers a few ways to return/update values. That'd drive me nuts running a function I wrote prior and then having to figure out what the global var it was creating is.

$v = _TimesTen(32)
MsgBox(0, "Test", $v)

$c = _TimesTen(21)
MsgBox(0, "Test", $c)

MsgBox(0, "V * C", "V * C = " & $v * $c)

Func _TimesTen($var)
    $var *= 10
   Return $var
EndFunc

Vs.

_TimesTen(32)
MsgBox(0, "Test", $v)

_TimesTen(21)
MsgBox(0, "Test", $c)

MsgBox(0, "V * C", "V * C = " & $v * $c)

Func _TimesTen($var)
    Global $v = $var * 10
    Global $c = $var * 10
EndFunc

You're *style* doesn't work. So we'd have to make two functions.

_TimesTenV(32)
MsgBox(0, "Test", $v)

_TimesTenC(21)
MsgBox(0, "Test", $c)

MsgBox(0, "V * C", "V * C = " & $v * $c)

Func _TimesTenV($var)
    Global $v = $var * 10
EndFunc

Func _TimesTenC($var)
    Global $c = $var * 10
EndFunc

I guess the way you are failing to understand what's wrong with declaring a global in a function is the same reason i'm failing to understand what's right with declaring a global in a function. It just doesn't make sense for the sake of sanity and reusing my code.

Edited by ZacUSNYR
Link to comment
Share on other sites

Melba thank you for your advice, I will try that option. The others just bashed me, but I am not surprised :x

ZacUSNYR: "global" statement in a function does NOT reset the value of a variable! It just defines that variable in case it is not - if I use that function in a script where this global variable is not being used thus preventing the error that variable is not declared.

I have a lot of functions which I share between my projects and I want to have them as much universal as possible, so for example if something goes wrong in a certain function it makes a debug log into a logfile in case that the parent script uses logging into file (has global $logfile variable defined so I don't need to pass this as argument every time I call my logging func) and puts some other variables into the logfile. If they are not present then nothing worse then an empty string being logged happens.

The example I used may not be very clear, but I don't see why it's not clear for SciTE :-]

Edited by LoWang
Link to comment
Share on other sites

  • Developers

The example I used may not be very clear, but I don't see why it's not clear for SciTE :-]

It isn't SciTE but Au3check ran by AutoIt3Wrapper that is showing the warnings.

The reason is pretty simple: AU3CHECK is not executing the script so isn't aware of the Global definition done by the Func thus gives a warning.

AutoIT3 takes the simple approach and doesn't worry about anything until it encounters a variable used that isn't declared.

Jos

SciTE4AutoIt3 Full installer Download page   - Beta files       Read before posting     How to post scriptsource   Forum etiquette  Forum Rules 
 
Live for the present,
Dream of the future,
Learn from the past.
  :)

Link to comment
Share on other sites

The others just bashed me, but I am not surprised :x

I don't think anyone bashed you, the rest of the posts (like mine) was explaining why it is how it is and suggesting alternative methods.

See thread to see what happened to someone who asked the same question the other day.

Edited by Mat
Link to comment
Share on other sites

f1()
.......................Insert 200-300 lines of code
msgbox(0,"",$v)
.......................Insert 200-300 lines of code
func f1()
global $v
$v=1
EndFunc

Is this necessary? I think it is a bug. And please before you bash me with your advices about code writing rules and such things and tell me I have to declare all variables at the script beginning:) think about it - I have a lot of functions in an include file and I don't really need to have my memory eaten by declaring variables which I don't always use. I want to call my function and have it declare all necessary variables which may or may not be used in a script in which I use that function. That's why I have the "global" statement in my functions to avoid error if the var is not used in a script which calls it. What do you say?

Is it Necessary..NO

Is it bad program practice yes....

BUT I could give you an example piece of code where placing globals in several "declare()" functions would be a good idea due to memory usage.

Though it would be an artifical construct with LARGE blocks of data.

The trouble with putting globals in functions is for the programmer. Take your example above insert the lines where I've mentioned and then try and fault find it. Lets say you ignore the SciTE warning place the global in a function and end up after lots of edits with code that looks like this.

.......................Insert 200-300 lines of code
f2()
.......................Insert 200-300 lines of code
f1()
.......................Insert 200-300 lines of code
func f1()
   global $v
   $v=1
EndFunc
.......................Insert 200-300 lines of code
func f2()
   msgbox(0,"",$v)
EndFunc

I'm guessing that No error (or if they are they will be ignored) will be generated at compile time.

This leaves your user to hit the error at run time when F2 is run before f1.

Not good for the user.

Hope that makes things a little clearer. :x

John Morrison

aka

Storm-E

Link to comment
Share on other sites

...

The trouble with putting globals in functions is for the programmer. Take your example above insert the lines where I've mentioned and then try and fault find it. Lets say you ignore the SciTE warning place the global in a function and end up after lots of edits with code that looks like this.

.......................Insert 200-300 lines of code
f2()
.......................Insert 200-300 lines of code
f1()
.......................Insert 200-300 lines of code
func f1()
   global $v
   $v=1
EndFunc
.......................Insert 200-300 lines of code
func f2()
   msgbox(0,"",$v)
EndFunc

I'm guessing that No error (or if they are they will be ignored) will be generated at compile time.

This leaves your user to hit the error at run time when F2 is run before f1.

Not good for the user.

Hope that makes things a little clearer. :x

...

I hope you do not mind me expressing my concerns about your attempt to clarify an issue. My response could be to anyone with a similar explanation about this topic. I will use your example as a reference for my concerns.

Using Globals in functions is not my preference if at all possible. My concern is that if I were to debug this code with the extra several hundred lines of code added to make it more complex then I would see f1() and say, not good code but it may still work. Now after that experience, I latter get to f2(), my thoughts are that the code is not good as $v has no declaration or even an assignment of $v to a value. This is what I regard as the major problem. No error handling exists in f2() to avoid issue. Now someone may say that this is a rough example. Perhaps may seem fine to say. But if you are trying to clarify something then why use an example that is (visually) flawed even without using Au3check or any other error checker? IMO, good code is about code that looks correct and behaves correct. If I have to search the script for a declaration or an assignment of $v then that is not good practice to me. It does not matter whether $v is declared as the first line of the script or any other considered thoughtful place. I still find a major dislocation of code and I regard that as not good code. If it does not look correct, then chances are that it is not correct. Any function within a script IMO should look correct and show independence including error handling if a variable issue is evident.

With a small alteration of the example, I get no errors from Au3check. I get code that looks valid to run without error. Oh, I used Dim which annoys some group of people, but at rare times it has use which can be valid. As I previously mentioned, using a Global declaration in a function is not my preference as it could be handled better by changing the code to avoid the risk of Global variable accidental changes of values. Using Global inside a function is still valid so I will use an example which displays valid code.

;.......................Insert 200-300 lines of code
$return = f2()
If @error Then
    Msgbox(0, "", 'Unable to continue as f2() errored with reason: ' & $return)
    Exit 1
EndIf
;.......................Insert 200-300 lines of code
f1()
;.......................Insert 200-300 lines of code
func f1()
   Global $v
   $v = 1
EndFunc
;.......................Insert 200-300 lines of code
func f2()
    Dim $v
    If Not $v Then Return SetError(1, 0, '$v is empty')
    Msgbox(0, "", $v)
EndFunc

I hope this assists to be clearer and improves the consideration of anyone with a different evaluation shown. :P

Link to comment
Share on other sites

G'day Mhz

The whole point was you can see the errors as it stands with the 200-300 lines of code removed.

BUT put those lines in (ie expand the code to a real situation) and the errors are impossible to find at compile time.

I stayed close to the authors original code to demonstrate the problems what could develope with this method.

The error checking you put in will definatly solve the potential problem.

But the programmer has to realise that there could be a problem in the first place to put the error checking in.

Also it removes the whole reason the author suggested this approach, the precieved benifit of reducing the runtime size.

My personal opinion is putting all the globals in the main part of the code (standard practice, best practice) will avoid all the problems and avoid having to add a lot more error checking code.

John Morrison

aka

Storm-E

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...