AlliedModders

AlliedModders (https://forums.alliedmods.net/index.php)
-   Code Snippets/Tutorials (https://forums.alliedmods.net/forumdisplay.php?f=83)
-   -   [TUT] The Use of Static Variables (https://forums.alliedmods.net/showthread.php?t=40340)

Hawk552 06-26-2006 09:10

[TUT] The Use of Static Variables
 
What is a static variable? It is basically a global variable that can only be accessed by the function it is declared in.

This means that:

Code:
#include <amxmodx> #include <amxmisc> public plugin_init() {     register_plugin("The Internet","Has","Spoken")         fnDoFunc()     iNum = 2 } fnDoFunc() {     static iNum     iNum = 1 }

Is NOT valid. Why? Because the static variable was declared in fnDoFunc, not plugin_init.

The example above does not exemplify the true power of static variables. If you're just going to zero it before you use it, use the operator "new". Declaring a new variable is not an expensive operation, simply the zeroing of it is.

But what can a static variable do?

Here's an example of the usage of a static variable vs. a new variable:

Static
Code:
#include <amxmodx> #include <amxmisc> public plugin_init()     register_plugin("The Internet","Has","Spoken") public client_connect(id) {     static szName[33]         get_user_name(id,szName,32)     client_print(0,print_chat,"the matrix has %s",szName) }

New

Code:
#include <amxmodx> #include <amxmisc> public plugin_init()     register_plugin("The Internet","Has","Spoken") public client_connect(id) {     new szName[33]     get_user_name(id,szName,32)     client_print(0,print_chat,"the matrix has %s",szName) }

But why is the static version faster? Because the memory isn't created every single time it's needed, rather it's left there, kind of like a global variable never loses its value ever after being used in a function.

So for example, take in this hypothetical sequence of events in a server:

Static
Code:

  static variable initialized
 
  Hawk552 joins server
  client_connect called
  static variable already exists
  get name
  print name
 
  *5 minutes later*
 
  zomg joins server
  client_connect called
  static variable already exists with contents "Hawk552\0..."
  get name -> now looks like "zomg\052\0...", however it ends at the first \0 so the trailing 52 doesn't matter
  print name

New
Code:

  Hawk552 joins server
  client_connect called
  new variable initialized
  get name
  print name
 
  *5 minutes later*
 
  zomg joins server
    client_connect called
  new variable initialized
    get name
    print name

And that is basically why static variables are useful.

3xr 06-26-2006 16:51

Re: The Use of Static Variables
 
Thanks for the info. BTW: Happy Birthday.

Cheap_Suit 06-27-2006 03:02

Re: The Use of Static Variables
 
hmmm interesting...

Can you tell me when to use it and when not to use it

Hawk552 06-27-2006 09:37

Re: The Use of Static Variables
 
Quote:

Originally Posted by Cheap_Suit
hmmm interesting...

Can you tell me when to use it and when not to use it

Well, in something like a loop, it's pretty useless, like this:

Code:
for(static iCount = 0;iCount < x;iCount++)

You'd might as well use new, because the = 0 section of it will make it the same expensiveness as using new. This goes for most other things like = get_user_frags(id) etc.

When using a huge ass array like a motd or menu it's generally best to use static because arrays are a huge hit on CPU, and making it static nullifies that. You must be careful about re-entrancy though, as in something being set from the last time it was used and using it for this instance anyway. If your script is enormous you might start running out of memory in which case you can use #pragma dynamic, with some value like 131072 (which is in bytes)

But as shown in my example one of the best ways to use this is something like:

Code:
static szName[33] get_user_name(id,szName,32)

Orangutanz 06-27-2006 21:21

Re: The Use of Static Variables
 
Quote:

Originally Posted by Cheap_Suit
Can you tell me when to use it and when not to use it

I would imagine a better example would of been if using Forwards such as: PlayerPreThink, StartFrame, Touch etc
All of which are very demanding forwards, so a static would be handy to reduce overhead in the long term.

One annoying thing with static is that you cannot assign as you can with new, example:
Code:

new team = get_user_team(id)
static team
team = get_user_team(id)

Also I'm uncertain about this as well:
Code:

static team, player
Would player be a static or a new? I assume static but we all know how buggy the Pawn compiler is!

Hawk552 06-27-2006 22:02

Re: The Use of Static Variables
 
Quote:

Originally Posted by Orangutanz
I would imagine a better example would of been if using Forwards such as: PlayerPreThink, StartFrame, Touch etc
All of which are very demanding forwards, so a static would be handy to reduce overhead in the long term.

One annoying thing with static is that you cannot assign as you can with new, example:
Code:

new team = get_user_team(id)
static team
team = get_user_team(id)

Also I'm uncertain about this as well:
Code:

static team, player
Would player be a static or a new? I assume static but we all know how buggy the Pawn compiler is!

I'm pretty sure that in your last example they would both be static.

BAILOPAN 06-27-2006 22:05

Re: The Use of Static Variables
 
Using static isn't really necessary if you initialize it like that. It's more appropriate for arrays.

Hawk552 06-27-2006 22:19

Re: The Use of Static Variables
 
Quote:

Originally Posted by BAILOPAN
Using static isn't really necessary if you initialize it like that. It's more appropriate for arrays.

Which is what I said, because setting it after makes it take pretty much the same CPU as using the new operator. On top of that it just kind of sits around even after the function is used, which is kind of a waste of memory, even if it's only 4/8 bytes.

PM 06-30-2006 06:57

Re: The Use of Static Variables
 
Quote:

Originally Posted by Hawk552
Which is what I said, because setting it after makes it take pretty much the same CPU as using the new operator. On top of that it just kind of sits around even after the function is used, which is kind of a waste of memory, even if it's only 4/8 bytes.

Just a technical note: It sits around even before the function is used. Static variables in PAWN (and in all C/C++ implementations I know as well) are implemented exactly as global variables, as you said. In the case of PAWN, this means that they are stored in the DAT section, which is always present in its entirety. As you said, the only difference is that the scope of the variable is different (for the compiler, not the abstract machine). You cannot access a static variable defined in one function from another function, while global variables are that; global. However note that you can modify the static variable from another function using "inline assembly" ( #emit compiler directive ) if you know its location in the DAT section (which you can find out by counting or more easily by disassembling the output .amxx file), but you would only do this if you are insane.

v3x 06-30-2006 08:07

Re: The Use of Static Variables
 
oh, hello pm,

maybe you should make a tutorial on the use of static variables instead :up:


All times are GMT -4. The time now is 09:14.

Powered by vBulletin®
Copyright ©2000 - 2024, vBulletin Solutions, Inc.