Hi!
When should I use Local Variables?

Is it wrong to declare hwnd not in WinMain as Local?
Where are the advantages?

I had some thougth, but didn't know if they are right:

1. When a Var is Local it can't be changed from another function(procedure)?
2. You can declare the same VarName several times if they are Local and in different function(procedures)?
3. It's more secure because you can't change them outside the proc by mistake?
4. You should only declare them as locals when you sure that you really only need them in that proc/function?

Is that right, or do I misunderstand sth.?
Posted on 2002-08-11 11:10:56 by Subby
They're unloaded from memory when you return from the proc.
Posted on 2002-08-11 11:40:08 by goofee
Subby,
it depends a lot on your programming habits and the purpose of the variable. I tend to go by the life of the variable. Ex, for a window handle, since the window exists all the time, I keep it global. For something like a file handle I keep it local cause I'm bound to close it right away. And if I want to reuse the variable name, I make it local.

Locals of course take less memory cause they are allocated at run time, but are not ideal for large allocations (arrays or long string buffers). Moderate sized strings or structures that have short life spans (like PAINTSTRUCT) are good for LOCAL.

--Chorus
Posted on 2002-08-11 11:43:31 by chorus
sorry if this questions i lil offtopic but what acctually compiler generates when he sees creation of local variable

we type for masm this:
LOCAL blah:DWORD

so what should this look like like this in opcodes
Posted on 2002-08-13 18:01:24 by Mikky

what acctually compiler generates when he sees creation of local variable

we type for masm this:
LOCAL blah:DWORD

so what should this look like like this in opcodes


You can easily find out by assembling a test code. :grin:
Oh well, here is the answer: The code


foo proc
local bar:dword
[more local variables...]
[function body]
foo endp

will be assembled into


foo:
push ebp
mov ebp,esp
sub esp,XXXX
...

where XXXX is a number given by the sum of sizes of variables, and the size of a variable is determined by rounding up to the next 4 byte boundary. E.g. local s:byte will have size of 4 bytes.
Posted on 2002-08-13 18:20:16 by Starless
one more advantage:

if you extend your project and make more than one instance of your program at the same time
(some kind of multitasking), you dont need to change something, otherwise your different
modules will access the same global variables. This is no problem if the variables are readonly,
but other things will lead to wired and heavy to debug errors.
Posted on 2002-08-14 03:50:05 by beaster
beaster clarify what you mean...
Each instance of a program runs in it's own memory space so unless specifically coded to do so one instance of a program won't be able to access another's variables.
Posted on 2002-08-14 03:59:56 by MArtial_Code
Goofee confused me a little. Is the value of a local variable really restored? Until know I thought the value is lost, if the procedure returns!

:( Marwin
Posted on 2002-08-14 06:36:31 by Marwin
Marwin your thinking is correct the stack varibles are lost on return. this is also what goofee is saying only in a different way.
Posted on 2002-08-14 06:42:41 by MArtial_Code
beaster clarify what you mean...
if you use a dll multiple times, you are right.
But image something like WORD, where you have a main program and a number of documents,
each in its own child window. Maybe the childwindow has a <dwZoom> variable, that holds the
magnification for the document. You can store this global, if you have only one child window / document
at one time. If you decide (also some time later during developing your project) that you need
more than one document window at one time, you need to make <dwZoom> local for each window

Maybe using LOCALs will also not solve this problem, but if you did not use GLOBALs at all, such a
change will not become a lot of work. In this example you can put the <dwZoom> as userdata to
each windowhandle (e.g. SetWindowLong) and read it into a LOCAL variable whereever you need it.
Posted on 2002-08-14 06:57:55 by beaster
Oh, missunderstanding between two different languages :tongue:

Marwin
Posted on 2002-08-14 07:08:37 by Marwin
The choice between GLOBAL and LOCAL variables is the scope in which you need them. In assembler, the difference between a value placed in the DATA or DATA? sections which has GLOBAL scope in the module or a LOCAL value that is created on the stack at the beginning of the procedure and destroyed at the exit of the procedure.

If a value is only needed during a procedure, it makes sense to make it LOCAL as you can reuse the name in another procedure with no problems and it means you can isolate a procedure by using LOCAL values. Stack locals are generally faster as they are recently created and should be in the DATA cache. This is what Intel recommend for values that only need scope within a procedure.

I personally make a habit of making handles GLOBAL so I can use them across many different procs without a messy parameter list for procedure calls but where I don't need GLOBAL scope, I regularly use LOCAL values.

Regards,

hutch@movsd.com
Posted on 2002-08-14 09:57:11 by hutch--
Beaster, in a situation like you describe I usually keep those variables global (unless I only have only one such variable). What I usually do is keep all window specific data in a global structure and use SetWindowLong to set a pointer to that structure. The call to SetWindowLong is costly and if you need several variables, you will be calling it multiple times.


If there is only one such variable, however, then your way works great -- no point in calling the API to get a pointer to a DWORD :)

--Chorus

PS. I love how there can be misunderstandings when you go German to English and back to German :)
Posted on 2002-08-14 10:58:25 by chorus
Have you ever tried recursive function calls which use globals?
I haven't, but I don't think I want to...

Mirno
Posted on 2002-08-14 11:36:51 by Mirno
Afternoon, Subby.

As Mirno has pointed out...
If you're going to make a recursive proc, you've got to use LOCAL vars - GLOBAL vars won't work (obviously ;) ).

Each time the proc calls itself, you need it to retain the values of the vars for when the calls return; and these would be changed if you used GLOBAL vars.

This is only regarding the vars which are specific to the proc itself. Any vars which don't change over the lifetime of the recursive calls, can be placed as GLOBAL.

Cheers,
Scronty
Posted on 2002-08-14 17:09:52 by Scronty
Subby,
i am a little late posting to this thread, and hutch has already covered the technical aspect of local and global vars and their scope, but here is my opinion anyway.....

It is advised that you learn the basics of programming before starting asm, and learning variables and their scope is one of the absolute basics you should know, and those basics apply no matter what language you are programming in. A quick search on google using the search string:

"local variables" "global variables" "static variables"

will turn up heaps of information for you to trawl through, you really need to understand these concepts. Choose pages with nice easy languages like VB on them, they will be easier for you to understand, and like i said the concept is the same no matter what the language is. I am not trying to discourage you in any way, and the guys have already offered you some good advice, but this is a basic idea that you MUST understand before going any further.


<edit>
Oh yeah, and i advise that you don't try even experimenting with recursion until you thoroughly understand variable scope....
</edit>
Posted on 2002-08-15 07:04:56 by sluggy
For anyone who's interested, it's very possible to write recursive routines using only globals.

It's a pain because you need to copy data to/from your own stack (which would be global, to satisfy our globals-only condition), instead of using what many processors (including our x86) provide for free.

It's also possible to write recursive routines, without locals, by using PUSH and POP instructions to save and restore "local" data stored in globals.

Keep in mind that registers are, in effect, global storage. So managing multiuse globals is as easy as, and as difficult as, managing registers.
Posted on 2002-08-15 15:46:12 by tenkey