Magisch
Magisch

Reputation: 7352

Is passing global variables to functions problematic?

Consider following function declaration:

int abmeld(char *strsend)

which is called like this

abmeld(str);

where str is a global variable declared and initialised at the start of the program file (after the includes) like this:

char str[300] = "";

Now I already know this is unnecessary code (you can access and modify the char array from within any function without passing it anyways), but is this actually otherwise problematic?

Are there consequences (like hard error possibilities, or undefined behavior) that can happen as the result of passing an already globally scoped variable to a function?

Upvotes: 24

Views: 12490

Answers (7)

zwol
zwol

Reputation: 140768

There is a case where this could be problematic: if abmeld already does something with the str global. As a trivial example:

extern char str[300];

void abmeld(const char *s)
{
    snprintf(str, 300, "abmeld: %s\n", s);
}

then abmeld(str) has undefined behavior, because snprintf has undefined behavior when its destination buffer overlaps any of its inputs.

This demonstrates one of the reasons global variables are troublesome: in order to know what's safe to pass as an argument to abmeld, you have to know not only that it writes to str (which would surely be documented), but how it does that — it could have been written

void abmeld(const char *s)
{
    size_t n = strlen(s);
    size_t maxcopy = min(n, 300 - sizeof "abmeld: \n");
    size_t after = maxcopy + sizeof "abmeld: " - 1;

    memmove(str + sizeof "abmeld: " - 1, s, maxcopy);
    memcpy(str, "abmeld: ", sizeof "abmeld: " - 1);
    str[after] = '\n';
    str[after+1] = 0;
}

and then it would have well-defined behavior no matter what s points to, as long as it's a valid C-string.

Upvotes: 12

Giorgi Moniava
Giorgi Moniava

Reputation: 28674

Now I already know this is unnecessary code (you can access and modify the char array from within any function without passing it anyways), but is this actually otherwise problematic?

It doesn't matter to the function whether it receives locally or globally defined variable. Issues with global variables are related sometimes to the fact that you might not know from which parts of the program you are accessing/changing its value. Thread safety maybe also relevant.

Upvotes: 8

displayName
displayName

Reputation: 14389

  1. The method abmeld(char *) is only supposed to modify/work with the argument provided to it. While it may be bad to pass a global variable to this method, yet that doesn't prohibit anyone from calling this method with any other char *.

    • For example, if this method checks whether the string pointed to is palindrome, then writing this method exemplifies good coding. Now anyone can call it every time he/she wants to know whether the string is palindrome or not.
  2. Now I already know this is unnecessary code (you can access and modify the char array from within any function without passing it anyways), but is this actually otherwise problematic?

    • It may not be unnecessary code as explained above. The purpose of writing a new method is to compartmentalize one piece of work. In other words, a method should do only one thing. Unless the method abmeld(char *) has been written to exclusively modify that particular global variable (and even that may be a good thing), the code is perfectly ok the way it has been written as long as it is doing one thing with the argument provided to it.

    • There are numerous examples where this code may be problematic and the problems are intuitive. For example, there may be more methods which may be modifying/working on the global string. But, those problems are the problems which arise whenever you use a global variable. To get rid of those issues, you have to get rid of the global var and not the method because it isn't the method's fault that it is being used with a global var.

  3. Are there consequences (like hard error possibilities, or undefined behavior) that can happen as the result of passing an already globally scoped variable to a function?

    • Cannot say this authoritatively but I don't know of any. Didn't read any book either which advised against passing global vars to functions.

Upvotes: 3

I would say the opposite, it is almost never problematic to pass a global to a function (and it is usually dirty to use a lot of globals, the code becoming unreadable).

A function which depends lightly (or not at all) on the global state is often more readable and more understandable than a function using a lot of global (or even static) variables. A global variable changed in many functions makes your program messy to understand.

(never forget that you code not only for the computer, but also for your colleagues -perhaps even yourself in a few months- who would have to improve your source code)

Also, functions using global state are typically not reentrant.

At last, undefined behavior is mostly orthogonal to global vs argument data. In particular, a buffer overflow can occur both with a global variable, or with a pointer to some array (such as an argument or some local variable) .

A very crude rule of thumb would be to avoid loading the developer's brain with more than 7 items (magical number 7, + or - 2); hence the folklore rule to avoid more than 7 arguments or more than 7 globals.

Upvotes: 32

MSalters
MSalters

Reputation: 179991

It's very, VERY common to pass globals to functions. Example:

const char* global = "Example";

void foo() {
  printf("%s\n",  global );
}

Obviously this passes a global to printf. The C language by design makes this usage safe. A buggy implementation that trips over this would quickly be called out.

Upvotes: 7

Abhineet
Abhineet

Reputation: 5409

No, not at all.

Now I already know this is unnecessary code

Not always. In the case when your function does not have a default argument, then you have to comply with the function prototype and pass the global variable. The function won't care, whether the pointer points to local or global variable, though.

/* main.c */
char str[300] = {0};
int abmeld(char *strsend)
{
  /* Do something...process strsend */
  return 0;
}

int main( void )
{
  abmeld(str); /*Cannot pass void here as abmeld expects a char* */

  char localstr[10] = {0};
  abmeld(localstr);

  return 0;
}

Upvotes: 6

Jaffer Wilson
Jaffer Wilson

Reputation: 7273

You want to pass global variable to the function. It's simple that function you are using, requires parameter then you have to pass the parameters of the type of the argument that is required in the function.

Here, there is no concern or issue for passing a global variable or a local variable. You have to take care of the datatype of the argument that is to be passed.

Upvotes: 3

Related Questions