4

I am newly learning C Programming.

When we have a C Program with lot of functions, parameter passing, calling and all - It becomes a great problem as to which variable must be declared where.

My question is: If I declare all the variables (or atleast the variables that are confusing me) as Global Variables - my problem will be solved - but is that a Good Practice?

3
  • The best way to learn is through examples. Make the code as clean as possible and then submit it to the codereview stack exchange. The only globals that make sense are constants, but these should still be properly scoped.
    – Job
    Jul 11, 2012 at 19:46
  • 6
    Solve the right issue. The problem is in your confusion, not in the variable scope.
    – mouviciel
    Jul 12, 2012 at 8:34
  • 1
    @mouviciel - that is a classic comment, describing one of the main problems with software design! +1 May 12, 2013 at 23:08

9 Answers 9

9

Others already stated that global variables are not the solution. Here are some hints for managing local variables:

  1. Some people declare their variables at the latest possible line (right before using them the first time). Others declare them all at the top of the function body (which is more compatible with very old standards). Either is fine, but choose one style and stick with it throughout a program.

  2. If you find that you need many local variables in one function, it's a sign that you should split this function up. How many variables are too many? I'd say that more than 5 are uncomfortable. More than 10 unforgivable.

  3. If you pass many arguments (more than 4) to a function, that's also a bad sign. Often, this can be solved by splitting the function into two or more smaller functions. Sometimes, you can aggregate the arguments into a struct and pass this around.

  4. Properly name your functions and variables! I cannot emphasize this enough. Do not use names such as hlwrld or ac. Use helloWorld and accumulator. If you feel that those take too long to write, don't worry. You'll get faster at typing. And even if you don't, the time you save on debugging far outweighs the additional time for typing.

19

No, this causes far more problems than it solves. It is VERY BAD practice, and a classic anti-pattern. Don't do it.

One of the main problems is that it is much more difficult to discover how a global variable gets changed, and what the impacts of changes are, than when you have values which isolated from the rest of the code by passing them into functions.

1
  • 1
    One of the really neat things about globals is that you can hide them. You declare them in one .c file, and it's .h file. Then you sprinkle that .h file all over. As you start to work, you end up with more and more .h files referenced. Then you end up playing "Find the Global". For extra fun, put the same variable name in different .c/.h file combos.
    – Paul
    Jul 16, 2012 at 20:08
7

A big part of learning to program well is learning to design your program so that the parts that need to know about each other do, and the parts that don't need to know about each other don't.

Imagine starting a company. When you have three or four employees, everybody naturally knows everybody else, and things work fine. But that doesn't scale even to 100 employees, let along 1,000. At some point you have to start organizing your employees into departments that are each responsible for certain aspects of the business. Employees outside the Accounting department shouldn't go messing with the books, and employees outside the shipping department shouldn't be shipping products. Imposing structure on the business makes things work better -- it makes the business work in an organized, predictable way. That structure might irritate the old-timers who are used to doing a little bit of everything, but it's necessary for the company's growth.

The same thing is true for programs. When you're writing Hello, world! or FizzBuzz or Tic Tac Toe, all your code fits in a single file and you don't need to think much about structure. But that doesn't scale. When you start writing programs that are more complex, you have to start imposing structure on the code. You have to think about how to group tasks, what information is required for each module to do it's job, and how different modules will communicate.

Using global variables for everything is like running a company where all the employees know each other and know everything about the business -- it'll work, for a while, but it makes it hard to grow. The sooner you learn to organize your program and the flow of information through it, the sooner you'll have learned what programming is really all about, and the sooner you'll be able to write useful programs.

1

I don't remember any good pattern for global variable, but this is definitely not. And if you having too much parameters it's a sign that you probably need refactor your function.

1

In my experience, the cleanest way to do this is to create a data structure which contains all the variables that you require, and pass a reference to this structure to all your functions.

There is one valid reason to have a global variable, and that is when you need to access this data structure from within a signal handler, either to reload data or to cleanup and exit from the application.

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

struct my_data { int a, b, c; };
static struct my_data *_global_cfg = NULL;

void sigint(int signo);
struct my_data * my_init_data(void);
int my_processing(struct my_data *cfg);

int main(void) {
  struct my_data *cfg = my_init_data();
  signal(SIGINT, sigint);
  return my_processing(cfg);
}

void sigint(int signo) {
  printf("SIGINT: a=%d\n", _global_cfg ? _global_cfg->a : 0);
  exit(EXIT_SUCCESS);
}

struct my_data * my_init_data(void) {
  struct my_data *ret = calloc(1, sizeof(*ret));
  _global_cfg = ret;
  return ret;
}

int my_processing(struct my_data *cfg) {
  if (cfg == NULL) return -1;
  while (1) {
    printf("%d - Waiting for SIGINT\n", cfg->a++);
    sleep(1);
  }
  return 0;
}
0

no it is not a good practice as it will polute the global namespace (eventually you'll run out of names) and globals can be changed anywhere

if you have a set of parameters passed togheter often you can combine them in a struct that you can pass (pass a pointer if it becomes too big to be copied around)

2
  • 5
    "Eventually you'll run out of names" as a reason to not use globals just made my day ...
    – user39685
    Jul 11, 2012 at 13:19
  • @MattFenwick well meaningfull names at least unless you are using an old c compiler that can only handle identifiers up to 16 chars Jul 11, 2012 at 13:24
0

My suggestion is-

  • Split your code in several source files. Keep related code together and unrelated code separate. I mean modularize the project.
  • Try to pass parameters instead of using global variables for read-only purpose. For the parameter which will be changed in some function, use pointers.
  • Also consider using pointers for passing big data like structures.
  • If desperately needed, use global variable in the file scope by using 'static' modifier. Then the variable will be accessible from that file but not from other files.
0

In a word,

NO!

Don't EVER do that! NOT EVER!

Take special note of Why is Global State so Evil?

2
  • 3
    -1: One thing more evil than Globals is out right dogma.
    – mattnz
    Jul 12, 2012 at 8:26
  • @mattnz It serves its purpose, especially for beginner programmers. Before you know when it's legitimate to break the rules you have to know what the rules are and how to adhere to them.
    – GordonM
    Jul 12, 2012 at 9:03
0

Certain variable names tend to be used over and over again. For example, temp,i,theVar, and counter. It is better to give them a small scope so that you don't find yourself spending too much time creatively coming up with variable names, only to spend more time remembering them.

Have every variable be global and you'll end up with names like temp2, theOtherVar, timer (not to be confused with counter), loop controls reaching every letter of the alphabet, etc..

Limit the scope if you can. If only one function will use a variable, declare it in that function. You should only make a variable global if you plan to use it everywhere throughout your program. And even then it isn't always the best idea.

The whole point of having functions is that you can encapsulate pieces of logic. If, for example, you have a function that finds the distance between two coordinates, you should be able to pass the coordinates to it, get the distance back, and not have to worry about what happened in between. But if the function uses a global variable, and you accidentally modify it elsewhere in the program, you may spend hours trying to figure out why your function is acting unusual.

2
  • 1
    "You should only make a variable global if you plan to use it everywhere throughout your program." And even that is a bad excuse. Just because it's used everywhere doesn't mean it should be global.
    – CaffGeek
    Jul 11, 2012 at 20:14
  • -1 : "You should only make a variable global if you plan to use it everywhere throughout your program." - Although I do not subscribe to the "Globals are the root of all evil camp", you need a better reason to justify a global than this.
    – mattnz
    Jul 12, 2012 at 1:48