Page 1 of 1

Static Functions and Variables in C Rate Topic: ***** 1 Votes

#1 stackoverflow  Icon User is offline

  • D.I.C Addict
  • member icon

Reputation: 164
  • View blog
  • Posts: 545
  • Joined: 06-July 11

Posted 13 July 2011 - 10:29 AM

Static Functions and Variables in C


Disclaimer:

Static is one of C's mysteries. It is odd because it has two completely unrelated uses. This is quite the little puzzle for a language learner. I looked around for a tutorial and I was unable to find one. I thought it may be useful to include one. I hope this proves useful. I was originally going to write about static functions in a future-- larger-- tutorial, but the tutorial I am designing and planning is too large. I decided to break it up into a couple smaller chunks. I am doing this static tutorial as one of those chunks.

Target Audience:

The audience I target is low to mid level C programmers. Although many books write about static functions and static variables very few actually explain when and how to use them-- or more importantly why they were included to begin with. I hope the audience can take at least 2 things from guide. First-- I hope the audience is able to use better encapsulation in C. Second, I hope the audience feels comfortable using static functions.

Side Bar:
I have personally never needed to use very many static variables, but I feel understanding them is important. On the other hand static functions are very useful and I personally think people do not use them enough.

Encapsulation:

Before we dive into the two meanings of static we should understand a little about encapcsulation first. Encapsulation basicly states we should limit the scope of our functions and variables. By limit the scope-- we essentially mean each variable and function should be give only the minimum visibility it needs to do its job.

You may be familiar with encapsulation in object oriented languages. If you are familiar with C++ or Java you may be familiar with scope modifying keywords such as public, private, protected etc. C does not have these scope modifying abilities.

However, non-object oriented languages like C also practice encapsulation. C has static functions as a way to maintain a little encapsulation. Understanding that and designing your functions and variables with it in mind will make you a better programmer. This brings us to static and why we should understand it.

The two odd meanings of static:

Static is incredibly odd in the sense that it has two very different-- almost opposite-- meanings. The first meaning applies when it is used with functions, and the second when it is used with variables. Let's take a closer look.

The first meaning-- static functions:

In order to test static functions you first need to be able to compile multiple source files-- I assume you have the ability to produce two different source files and compile them. With that addressed-- let's continue!

Static functions are much like private methods in Java or C++. A private method is a method which is only used by a class and can't be used outside of it. In C, we can declare a static function. A static function is a function which can only be used within the source file it is declared in.

First, I will give you a working example. There are two files-- main.c which is our main program. Our main program will call our custom mini-library called randomnum. We designed our randomnum library to consist of 2 functions. One is a public function called getRandomNum which returns a random number between 1-1000. The second function in the library is a private function called seedRandom. Anyone that has used rand in C knows you need to seed rand. In this case we make seed a private function so the outside source files can't mess with it. This is an example of encapsulation-- we hide the details of our library.

main.c
#include <stdio.h>
#include "randomnum.h"

int main(void)
{
  printf("Random Number - %d\n", getRandomNum());
  return 0;
}



randomnum.h
#ifndef RANDOMNUM_H
#define RANDOMNUM_H

#include <stdio.h>
#include <stdlib.h>
#include <time.h>


/**
* getRandomNum - returns a random number between 1-1000
* @return: an integer between 1-1000
*/
int getRandomNum(void);

/**
*  seedRandom - seeds our random function
*  @note: this function is private
**/
static void seedRandom(void);

#endif


randomnum.c
#include "randomnum.h"

int getRandomNum(void)
{
  seedRandom();
  return rand() % 1000 + 1;
}

static void seedRandom(void)
{
  srand(time(NULL));
}


If all went well you should see the output-- a random number. Not so interesting. However, if we violate our scope we can make it a little more interesting. Here is a new main.c which violates the encapsulation.

#include <stdio.h>
#include "randomnum.h"

int main(void)
{
  /* Error - private function seedRandom() */
  seedRandom(); 
  printf("Random Number - %d\n", getRandomNum());
  return 0;
}


Well there you have it-- if you try to compile this you should get an error. Something along the lines of,

Quote

main.c:(.text+0xa): undefined reference to `seedRandom'


It is undefined because main can not see it-- it's hidden/private to the randomnum file(s).

In conclusion, static functions are great for sub-functions within a file. If you define some special functions that do busy-work inside a file multiple times it's probably best to declare them static and make sure the user (programmer) of your code does not use those same functions.

The second meaning-- static variables:

The second meaning is when static is used with a variable. This has nothing to do with static in the function sense. Static when used with a variable means the storage will be allocated at compile time and remain intact for the entire cycle of the program's execution. You may be thinking, "Isn't a global variable the same thing?" and you are right. A global variable uses static storage automatically. You probably hear people saying, "You should avoid global variables at all cost!" and they are also right. Global variables violate encapsulation because they don't hide data-- they simply give it to everyone. That is generally a bad style to program with.

I won't go into using global variables because it's something that should be avoided. I will show a snippet of how you could use static inside a function that returns a variable.

#include <stdio.h>

char* getBob(void)
{
  static char bob[3] = "bob";
  return bob;
}

int main(void)
{
  char *name = getBob();
  printf("%s\n", name);
  return 0;
}


Try this code with static and try it without it.

Why declare bob as static? Because bob was declared inside a function. A function has auto (automatic) storage. That means when the function returns those variables are popped off the stack and never to be seen again (can be over wrote by new variables popped on the stack). If you used this code without static it may or may not display the correct name in this simple case. It's possible the memory would still be intact and display the name, but the behaviour is actually undefined if you don't include static. Static makes sure the variable is not automatic-- instead it is allocated for the remainder of the program.

To conclude static variables-- for the most part they are not needed (like in the global variable case). When declaring a global variable static storage is automatically assigned and using the static keyword is pretty much pointless. When using static in other contexts it may be useful if you need to return data that must remain intact for the remainder of the program. Think about it carefully before deciding to use it!

After thoughts:

Building a program is a lot like building a house. Building a house takes a lot of steps. As long as you break down these steps into small steps you can usually come to a better solution. Along the way you may want to hide some steps you took to build your house. Besides-- no home owner wants to see your plumbing and electrical wires hanging around. We want to hide these details from everyone. The only people that are concerned with them are the builders.

We should strive to build programs like houses. Let's not abandon encapsulation in C because it doesn't have the abilities that object-oriented languages have. Instead let's make the best of what we have-- static functions.

As for static variables-- use them with care.

Is This A Good Question/Topic? 3
  • +

Replies To: Static Functions and Variables in C

#2 PlasticineGuy  Icon User is offline

  • mov dword[esp+eax],0
  • member icon

Reputation: 281
  • View blog
  • Posts: 1,436
  • Joined: 03-January 10

Posted 16 July 2011 - 03:43 AM

> Instead let's make the best of what we have-- static functions.
Or just program in C++ in the first place :P.

Great tutorial for those newer to the language.
Was This Post Helpful? 0
  • +
  • -

#3 Xploit_  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 6
  • Joined: 02-August 11

Posted 02 August 2011 - 07:23 PM

Does this mean I should still use static functions when dealing with multiple files in C++?
..or does this practice only deal with programming in C?
great tutorial; thank you! ^_^
Was This Post Helpful? 0
  • +
  • -

#4 stackoverflow  Icon User is offline

  • D.I.C Addict
  • member icon

Reputation: 164
  • View blog
  • Posts: 545
  • Joined: 06-July 11

Posted 06 August 2011 - 02:30 AM

It can be used along the same lines in C++. However, C++ has better encapsulation within classes (public, private, protected etc). The usage of static has declined a lot but can be used.

This post has been edited by stackoverflow: 06 August 2011 - 02:31 AM

Was This Post Helpful? 0
  • +
  • -

#5 Xploit_  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 6
  • Joined: 02-August 11

Posted 07 August 2011 - 09:50 AM

awesome, I suppose i'll use it for extra protection; knowing that it can't be used outside the class OR outside the file!
Was This Post Helpful? 0
  • +
  • -

#6 PlasticineGuy  Icon User is offline

  • mov dword[esp+eax],0
  • member icon

Reputation: 281
  • View blog
  • Posts: 1,436
  • Joined: 03-January 10

Posted 13 August 2011 - 06:59 PM

No, don't do that. static inside classes means something completely different. It's still a function accessible globally, but it's a member of a class e.g.
// foo.cpp
#include <iostream>
class Foo
{
    static void Do ();
};
void Foo::Do ()
{
    std::cout << "Foo\n";
}
// main.cpp
int main ()
{
    Foo::Do();
    return 0;
}

Was This Post Helpful? 0
  • +
  • -

#7 Xploit_  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 6
  • Joined: 02-August 11

Posted 15 August 2011 - 05:31 PM

what are the most common reasons why i would want to use static variables/functions in C++
just trying to get this understood so i never make a mistake with it
Was This Post Helpful? 0
  • +
  • -

#8 PlasticineGuy  Icon User is offline

  • mov dword[esp+eax],0
  • member icon

Reputation: 281
  • View blog
  • Posts: 1,436
  • Joined: 03-January 10

Posted 16 August 2011 - 12:46 AM

It's used when you need a single variable shared between all instances of a class, or a function that is logically part of a class and yet does not belong to any particular instance.
Was This Post Helpful? 1
  • +
  • -

Page 1 of 1