Reputation: 7352
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
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
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
Reputation: 14389
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 *.
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.
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: 3
Reputation: 1
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
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
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
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