Jump to content

Problem of compiler with this double "global const" declaration?


Recommended Posts

Never put an include line inside a function.

Include lines are always acted on by the compiler, there's no such thing as a conditional include.

Includes are placed into the main script at the point the #include line is in your script, so you just included the file into the middle of your function one_of_many_functions.

so what if I want to execute the content of that #included file only inside a function that I use very rarely?

is there a better alternative than putting that #include at the beginning of the whole script (therefore executing it every time)?

 

Link to comment
Share on other sites

  • Moderators

1.  Write a function that does what you want (again, declaring global variables is a no no really if it's going to be used outside the function (even if it's not, especially if it's not))

2.  Redesign your include, you have a flaw in it if it's calling functions without being called by you specifically (or unless it's setting global data).

Edit:
Keep this in mind.  An #include file is simply a directive used to create functions, globals, headers, etc to be "reused" by your main script.  Not to have separate functioning from your main script.
Edited by SmOke_N

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Link to comment
Share on other sites

Your scripts are read from top to bottom.

The includes are inserted the same way (from top to bottom where they are inserted in your code).

So, you're essentially doing:

ConsoleWrite($sString & @CRLF)
Global $sString = "Apple"

 

I still can't understand how can you see that I used the constant/variable before declaring it, as I first use it in the msgbox at very last line of the script, which is the one giving the error.  See again my last example:

As for using #include-once and not declaring functions inside functions I respected both rules since I'm including the file "<WindowsConstants.au3>"  included in AutoIT.

I understand that putting #includes inside functions usually have more risks than benefits but in my case:

1) I'd prefer the long list of declarations contained in WindowsConstants.au3 to be executed only if I use that function, that is sort of 1 time out of 1000.  I understand that the compiler unconditionally explodes the code WindowsConstants.au3 but I also understand that it's conditionally executed (just when I launch the function).  Am I wrong?

If I shift the #include outside the function as for general best practice it would execute it all the other 999 times when these long list of declarations are not needed too. Why not avoiding this?

Also, my function is a sort of function that when I use it (1/1000) I use it una-tantum (one time only).

2) I continue to not understand the logic behind the error "Variable used without being declared" in my example, as as far I can see the variable is clearly declared before use.  (?!)

Edited by Imbuter2000
Link to comment
Share on other sites

  • Moderators

Imbuter2000,

 

I understand that the compiler unconditionally explodes the code WindowsConstants.au3 but I also understand that it's conditionally executed (just when I launch the function). Am I wrong?

You are quite right. AutoIt directives (of which #include is one) are actioned before the script is "compiled". There is no such thing as a "conditional directive" or "conditional include" - if you add an #include line in your script it will be expanded every time, regardless of the surrounding code, but only executed if called at runtime. Remember that you can use the Au3Stripper utility to remove all unused functions and constants from your script before compilation, so you only keep those ones which might be called/used rather then the entire file, which lets you can get halfway to a conditional state. ;)

As to the error you get, you have already been told that there is a difference when you use " " or < > to enclose the include file name. If enclosed in < >, AutoIt first looks for the file in the standard include folder - and as you have called your personal include by the same name as a standard include, it is that standard include which is found. And as that standard include does not define the $foobar variable, you get an "undeclared variable" error. If you enclose the include name in " " then AutoIt first looks in the script directory and finds your personal include file which does declare the variable. Top Tip: Do not reuse standard include filenames - think up something new. :)

When I run the corrected code I get no error, although Au3Check will warn about the double include: :)

Func test()
 #include "constants.au3"
EndFunc
#include "constants.au3"

msgbox(0,"",$foobar)
However, if you run the code and actually call the function (thus causing the variable to be declared twice)

Func test()
 #include "constants.au3"
EndFunc
#include "constants.au3"

test()

msgbox(0,"",$foobar)
you get a "Cannot redeclare a constant" error. Nothing surprising there. ;)

All in all - it is your bad coding practices which cause the problem and it is nothing to do with AutoIt. :)

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

Melba, thanks for your tip about Au3Stripper.
but I'm still convinced that all of you didn't try my second/last example, that is the (only) correct one showing the problem.
Please, I invite you to forget my first example (in opening post) and to only try the following, I'm pretty sure that you will find something either wrong or missing in the compiler output:

; test1.au3:
#include "F:\AutoIt\myscripts\my_big_library_of_functions.au3"
#include <WindowsConstants.au3>
msgbox(0,"",$WC_ANIMATE)

; F:\AutoIt\myscripts\my_big_library_of_functions.au3:
; [omissis...]
func one_of_many_functions()
     #include <WindowsConstants.au3>
     ; [omissis...]
EndFunc
; [omissis...]

; WindowsCostants.au3  (originally included in AutoIT):
#include-once
; [omissis...]
; Window Classes
Global Const $WC_ANIMATE = 'SysAnimate32'
; [omissis...]

This is the compiler output: 

Compiler execution output:
"F:\AutoIt\myscripts\test1.au3" (4) : ==> Variable used without being declared.:
msgbox(0,"",$WC_ANIMATE)
msgbox(0,"",^ ERROR
->15:06:07 AutoIt3.exe ended.rc:1
Edited by Imbuter2000
Link to comment
Share on other sites

  • Moderators

Imagine your error being more like this:

Compiler execution output: "F:\AutoIt\myscripts\test1.au3" (4) : ==> Variable used before being declared.:

 

Edit:

AutoIt does NOT look ahead in the script, it looks behind.  If you keep that mindset, all should make sense.

And for the love of all that is holy, stop declaring includes in your functions.

Edited by SmOke_N

Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Link to comment
Share on other sites

Imagine your error being more like this:

Compiler execution output: "F:\AutoIt\myscripts\test1.au3" (4) : ==> Variable used before being declared.:

Edit:

AutoIt does NOT look ahead in the script, it looks behind.  If you keep that mindset, all should make sense.

And for the love of all that is holy, stop declaring includes in your functions.

 

Sorry for insisting so much but I try to be more simple than I can because I'm getting crazy in understanding your logic.

 

My code has 3 lines:

line 1: #include "F:AutoItmyscriptsmy_big_library_of_functions.au3"

line 2: #include <WindowsConstants.au3>

line 3: msgbox(0,"",$WC_ANIMATE)

$WC_ANIMATE is declared inside WindowsConstants.au3  (line 2 expanded)

 

Variable is used in line 3.

Line 3 comes after line 2, even after expansions of includes, even in execution.

Variable is used after declaration.

Where am I wrong?

And anyway, if an holy rule of not inserting includes in functions exists, why not writing this rule in the AutoIt Help page about #include?

Edited by Imbuter2000
Link to comment
Share on other sites

  • Moderators

Imbuter2000,

I have been playing with the code and I have the answer to your question. The paragraphs below are numbered in reference to the Lines you use in the pseudo-code above. :)

- 1. #include "personal include". Here the compiler adds the WindowsConstants file - the code is expanded and so there is a line defining the $WC_ANIMATE constant.

- 2. #include <WindowsConstants.au3>. As the WindowsConstants contains the #include-once line, and the include has already been added in line 1 above, the line is ignored by the compiler and no code is expanded.

- 3. msgbox(0,"",$WC_ANIMATE). This line comes into its own at run-time - and as the code inside the function (the expanded include code from Line 1) has not yet been run, the interpreter has not yet seen the line defining the $WC_ANIMATE constant - and so you get the error.

Additional comments:

- If you actually add a call to the function containing the original include before attempting to access it there is no error as the code has been read by the interpreter and the constant has been defined.

- And if you reverse the order of inclusion (by changing the positions of Lines 1 & 2) you will see that the error does not occur as the include file in the main script has been expanded (and the directive in the personal include ignored) which means that the $WC_ANIMATE constant definition line is now seen by the interpreter at run-time before it is used in Line 3.

I hope all that makes sense. Basically the include directives are actioned at compile-time but the code within them is only read at run-time. There is a similar reason behind the FileInstall requirement for a literal definition of the file to include. :)

Basically I repeat my earlier assertion that:

it is your bad coding practices which cause the problem and it is nothing to do with AutoIt

As SmOke_N said, stop declaring includes in your functions. :ohmy:

M23

Edited by Melba23
Typo

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

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...