Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

global variables

Status
Not open for further replies.

Kendel

Programmer
Apr 24, 2002
1,512
US
Hi,

I'm newbie. Can someone please tell me why we try to stay away from declaring global variable in C???

Thanks.
Kendel
 
The main reason you want to stay away from declaring global variables is because you dont want variables that any function can modify or access. This is especially important in larger systems. Variables could get modified and you wouldnt know it. That is what is nice about C++, you can declare a variable private to a given class.
 
You can also implement data hiding in C. Instead of making a variable "global," use static to prevent it from being exported to the linker and then write access functions:

static int foo;

int foo_get(void)
{
return foo;
}
void foo_set(int f)
{
foo=f;
}

Of course, you'll probably want some more code that performs access checks before returning or changing foo.

This differs from a private class variable in C++, though, in the sense that there's only one copy of foo shared by the entire program.

To get around this problem and retain the data hiding, you can create "opaque" types, effectively making all members of a struct private.

foo.h
-----
#ifndef FOO_H
#define FOO_H

/* Incomplete type, user can create
* pointers to struct foo, but its
* innards aren't exposed */
struct foo;
typedef struct foo foo_t;

/* Constructor */
extern foo_t *
foo_alloc(void);

/* Destructor */
extern void
foo_free(foo_t *);

/* Functions that operate on foo objects */
extern void
foo_print(const foo_t *);

extern int
foo_get_i(const foo_t *);

extern void
foo_set_i(foo_t *,int);

extern char
foo_get_c(const foo_t *);

extern void
foo_set_c(foo_t *,char);

extern double
foo_get_d(const foo_t *);

extern void
foo_set_d(foo_t *,double);

#endif

foo.c
-----
#include <stdio.h>
#include <stdlib.h>

#include &quot;foo.h&quot;

/* struct foo is defined here, making
* its definition unavailable to
* the user directly. */
struct foo {
int i;
char c;
double d;
};

/* Print a foo object */
void
foo_print(const foo_t *foo)
{
printf(&quot;%d; %c; %f\n&quot;,foo->i,foo->c,foo->d);
}

/* Accessor methods */
int
foo_get_i(const foo_t *foo)
{
return foo->i;
}

void
foo_set_i(foo_t *foo,int i)
{
foo->i=i;
}

char
foo_get_c(const foo_t *foo)
{
return foo->c;
}

void
foo_set_c(foo_t *foo,char c)
{
foo->c=c;
}

double
foo_get_d(const foo_t *foo)
{
return foo->d;
}

void
foo_set_d(foo_t *foo,double d)
{
foo->d=d;
}

/* Constructor */
foo_t *
foo_alloc(void)
{
foo_t *foo=malloc(sizeof *foo);
if (foo) {
foo->i=0;
foo->c=0;
foo->d=0.0;
}
return foo;
}

void
foo_free(foo_t *foo)
{
free(foo);
}

foo_test.c
----------
/* Test suite */
#include &quot;foo.h&quot;

int main(void)
{
foo_t *foo=foo_alloc();

if (foo) {
foo_set_i(foo,10);
foo_set_c(foo,'A');
foo_set_d(foo,8.88);
foo_print(foo);
foo_free(foo);
}
return 0;
}

The advantage is that the user must use the accessor functions to access or change members of the struct. The disadvantage is that the user can only create pointers to struct foo, because it is an incomplete type.
Russ
bobbitts@hotmail.com
 
Thank you all for the explaination. It's clear but kinda complicate to me. I just want to declare a global variable so I can access to it in any function. If I declare it locally, then I have to re-declare it in each function then I have to pass it out...too complicate. But I guess this is how C works. It's much easier in VB.

Again, thanks for your help.

-kendel
 
Kendel:

Steve McConnell, in his book, &quot;Code Complete, A Practical Handbook of Software Construction&quot; says these are the main reasons to limit the use of globals:

1) Inadvertent changes to global data
2) Bizarre and exciting aliasing problems with global data.
3) Re-entrant code problems with global data.
4) Code reuse hindered by global data.
5) Modularity and intelliectual manageability damaged by global data.

McConnell agrees with Russ above to use access routines to retrieve and update your global data. In fact, McConnell, at least during development, likes to lock his globals. You can check a global out, but it can't be changed until it's checked back in.

Kendel, this was an interesting thread. Thanks for starting it.

Ed
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top