You should not define global variables in header files. You should define them in .c source file.

  • If global variable is to be visible within only one .c file, you should declare it static.

  • If global variable is to be used across multiple .c files, you should not declare it static. Instead you should declare it extern in header file included by all .c files that need it.

Example:

  • example.h

    extern int global_foo;
    
  • foo.c

    #include "example.h"
    
    int global_foo = 0;
    static int local_foo = 0;
    
    int foo_function()
    {
       /* sees: global_foo and local_foo
          cannot see: local_bar  */
       return 0;
    }
    
  • bar.c

    #include "example.h"
    
    static int local_bar = 0;
    static int local_foo = 0;
    
    int bar_function()
    {
        /* sees: global_foo, local_bar */
        /* sees also local_foo, but it's not the same local_foo as in foo.c
           it's another variable which happen to have the same name.
           this function cannot access local_foo defined in foo.c
        */
        return 0;
    }
    
Answer from Tomek Szpakowicz on Stack Overflow
🌐
Code Quoi
codequoi.com › en › local-global-static-variables-in-c
Local, Global and Static Variables in C - codequoi
We can declare a local or global variable as a static. The static keyword has a very simple logic. A static variable is by default a global variable: stored neither in the stack nor the heap, it has the same lifespan as its program.
🌐
GeeksforGeeks
geeksforgeeks.org › c language › static-variables-in-c
Static Variables in C - GeeksforGeeks
Static variables are generally declared inside functions, but they can also be declared outside functions (at the global scope). Global static variables have their scope limited to the file they are defined in (internal linkage).
Published   July 23, 2025
🌐
Reddit
reddit.com › r/c_programming › when are static and global variables dangerous to use in c?
r/C_Programming on Reddit: When are static and global variables dangerous to use in C?
November 30, 2024 -

This is a very broad and open question. During my C learning journey I have been told to avoid using global and static variables. I am still not sure why that is the case.

This is a topic I want to learn more about because it is very blurry to me what exactly is dangerous/undefined behavior when it comes to global and static variables.

From what I understand, marking globals as volatile when dealing with signals can be important to make sure the compiler doesn't interfere with the variable itself, however, I have no idea why that is a thing in the first place and whether it is an absolute truth or not.

Then, there is the whole multithreading thing which I don't even understand right now, so I definitely need to catch up on that, but from what I heard there are some weird things with race conditions and locks to be wary of.

If anyone is well versed about this stuff or has recommended resources on this subject I would be interested to know :)

🌐
Cprogramming
cboard.cprogramming.com › c-programming › 178995-i-do-not-understand-static-global-variable-c.html
I do not understand static global variable in C
A "static" variable defined outside of any function in one .c file, is visible to any function defined after the definition of the "static" variable in that one .c file. The symbol is not passed to the linker and all references to the static variable are resolved by the compiler. I would avoid calling a file level static variable, global!
🌐
Northern Illinois University
faculty.cs.niu.edu › ~freedman › 241 › 241notes › 241var2.htm
Global Variables, extern, static, const
When a local static variable is created, it should be assigned an initial value. If it's not, the value will default to 0. A global static variable is one that can only be accessed in the file where it is created.
🌐
Medium
medium.com › @aserdargun › introduction-to-c-global-local-and-static-global-variables-d3bb76ca012c
Introduction to C — Global, local and static global variables
October 30, 2023 - Here, the word static indicates that a variable is local to the file in which it is declared. For example, suppose an array is declared as static inside a file containing two functions main(...) and init(...) . In this case, that array could ...
🌐
Scaler
scaler.com › home › topics › static variable in c
Static Variable in C - Scaler Topics
July 7, 2024 - To declare a static variable, we have to use the keyword static while in the case of global variable, if the variable is declared outside the main function without any special keyword, the compiler interprets it as a global variable.
Find elsewhere
🌐
OverIQ
overiq.com › c-programming-101 › local-global-and-static-variables-in-c
Local, Global and Static variables in C - C Programming Tutorial - OverIQ.com
When there is a conflict between ... ends. They are available to any function until the program is executing. A Static variable is able to retain its value between different function calls....
Top answer
1 of 4
11

Whenever the key is changed(by some other threads), my call back notifier is executed in which I update my static global variable with the new key. This key is used everywhere in the program to decrypt some data.

What is trapping you in this kind of thinking is the concept of "the key". It should be "a key".

You think of the key as global so anything that would hold it must be global. Imagine your requirements change and suddenly there are 5 keys running around.

Can't imagine that? Fine, imagine 5 systems, that do nearly the same thing, that must have different keys and all need to be part of your application. How much of your code could be reused?

The key belongs in a context. Within that context there will be only one key. But that doesn't mean there will only ever be one context.

Rather than force everything to find this key by knowing "the one true key" tell them what context they are in by passing them some way to find the key they care about.

That means the key will still only be stored in one place. But now only one place decides where that place is. If you make it global then everything has to know where it is and AGREE on where that is. Ick.

2 of 4
4

A static global variable is the same global variable, just with a limited compile-time visibility, as @5gon12eder notices above.

Global static state is prone to race conditions. If you have multiple threads accessing this state, you might need locking. If you only have one thread allowed to change the value, you may still have race conditions unless other threads make a copy of the value once and don't depend on repeated reads of the global variable returning the same value.

If you are an expert at writing lock-handling code, you may be fine with that. But likely you won't be asking this question then.

If you have a single-threaded program, these problems mostly go away; the remaining problems may be in unaccounted-for interactions between functions via the global value.

This all is well-known, just summed it up for you.

🌐
Unstop
unstop.com › home › blog › static variable in c | a comprehensive guide with coding examples
Static Variable In C | A Comprehensive Guide With Coding Examples
July 31, 2024 - This variable is declared outside of the function, making it a global variable. However, the static keyword limits its visibility to the current translation unit, meaning it can only be accessed within this source file, not from other files.
🌐
Microchip Developer Help
developerhelp.microchip.com › xwiki › bin › view › software-tools › compilers › c-programming › multi-file-projects › static-variables
C Programming Static Variables - Developer Help
A static variable is created when ... always exist—the only time they disappear is when power is removed. A global variable (declared outside of any function) has no choice—it must always be static....
🌐
Java Guides
javaguides.net › 2023 › 12 › difference-between-global-and-static-variables-in-c.html
Difference between Global and Static Variables in C
December 17, 2023 - A global variable is accessible from any function within the same program file, while a static variable's scope is limited to the function/block in which it is declared but its lifetime extends across the entire run of the program.
🌐
Hero Vired
herovired.com › learning-hub › topics › static-variable-in-c
Static Variable in C: A Comprehensive Guide by Herovired
Use static local variables when the data needs to persist between function calls. This keeps the variable’s scope limited to the function while retaining its value. This practice reduces the risk of unintended side effects, as the variable ...
🌐
Medium
medium.com › @firatatalay › essential-guide-to-variables-in-c-programming-understanding-local-global-and-static-33aede116f32
Essential Guide to Variables in C Programming: Understanding Local, Global, and Static | by Firat Atalay | Medium
July 30, 2024 - Essential Guide to Variables in C Programming: Understanding Local, Global, and Static Understanding Variables in C Programming In today’s class, we delved into some fundamental concepts in C …
🌐
Quora
quora.com › What-is-the-difference-between-a-static-variable-and-global-variable-in-C-C++
What is the difference between a static variable and global variable in C/C++? - Quora
Answer (1 of 11): All global variables are static, but all static variables are not necessarily global. What all static variables (including global) have in common is that they have a lifetime that lasts the duration of the program.
🌐
Reddit
reddit.com › r/c_programming › is there a difference between a global variable and a static variable in a function in terms of what the compiler produces?
r/C_Programming on Reddit: Is there a difference between a global variable and a static variable in a function in terms of what the compiler produces?
January 28, 2018 -

Is there a difference between a global variable and a static variable in a function? I'm talking in terms of the compiled code that is produced.

one.c

#include <stdio.h>
int test = 1;
void t1() {
    printf("%d", test);
    test++;
}
int main() {
    for(int i = 0; i < 10; i++) {
        t1();
    }
}

two.c

#include <stdio.h>
void t1() {
    static int test = 1;
    printf("%d", test);
    test++;
}
int main() {
    for(int i = 0; i < 10; i++) {
        t1();
    }
}

As far as I'm aware, creating static int like this is functionally equivalent of making a global variable. But when I compile them both with "cc -g -o one.o one.c" and then do "objdump -D one.o > one.txt" and diff one.txt with two.txt, there are differences. I can't figure out whether these are superficial differences or whether the compiler is somehow storing int test differently in each case.

Top answer
1 of 4
4
One big difference is that the "static int test = 1 " variable in void t1() is just in the scope of the function, no other function can see this value but the global "int test = 1" is visible for all other functions, below the definition and declaration and just because this behaviour it makes sense that the compiler treats both variable differently
2 of 4
3
From my diffing of the output from -S with GCC 4.8.5 sans optimization, it doesn’t look like there are any real differences in generated code. There’s a slight difference in the label name and ancillary goop around test, but otherwise it’s the same. If you declared t1 as static, you’d probably see some real differences, especially if you enable optimization. The only thing I can think of that can be different between one.c and two.c as they stand would be that in one.c, printf could potentially alter test (not that it would be a good idea; neither would it be a good idea to assume otherwise), so t1 will have to reload and spill test in between calls to printf. two.c doesn’t need to do that—it can potentially cache the value of test in a register across the printf calls, since printf can’t see test at all. More generally, the compiler can tell whether variables are potentially accessed or used in some way if it puts the effort in, and how you specify storage class, scope, and access in your declarations can greatly affect what optimizations the compiler has available. Note that it’s not necessarily possible to determine whether a variable isn’t used/accessed; the compiler will hopefully assume that a variable might be unless it can prove conclusively that it can’t, barring undefined/unspecified behavior per language specs. E.g., altering a value in memory from a debugger or via an incorrectly aliased pointer might not actually change the value of the variable that supposedly lives in that memory, but the compiler doesn’t have to care about that because it’s outside the bounds of what the language allows. If you make a global, externally-visible variable like your first test, the compiler would assume that it can be accessed arbitrarily when control passes outside its “observation.” (A volatile variable could be changed at any point.) For example, before main is called, the assignment test = 10 could be issued, which means its value upon entering main can’t be predicted. And as noted, the next iteration’s value of test can’t be predicted from the current value because printf could change it outside the compiler’s view. If you make a static global variable, the compiler can (theoretically) assume that, unless its address somehow escapes from the compilation unit, all uses of the variable must occur inside the declaring compilation unit. If you make a static local variable, the compiler can assume that, unless its address somehow escapes from the containing function/scope, all uses of the variable must occur in the declaring function/scope. The compiler has basically the same level of theoretical introspection into these two cases, since it can see everything inside the compilation unit at once; in reality, it’s usually somewhat easier to predict usage within a single function/scopre, since differences in argument or externally-scoped values can cause an explosion in the number of cases the compiler has to consider. If only the compiler is able to optimize things, compilation units are the outer bound for this kind of analysis, but with link-time optimization the linker can potentially make similar guesses as to access/use with respect to all LTO-enabled objects in the statically-linked portion of the final executable image. If LTO is enabled for everything and libc is statically linked in, it may be possible to completely eliminate test in both examples, and just pass values 1 through 10 to printf directly. It may even be possible to emit a single fputs call of the string 12345678910 to stdout instead, with no t1 or calls to printf either.
🌐
Quora
quora.com › Why-are-global-variables-different-from-static-variables-in-C
Why are global variables different from static variables in C ? - Quora
Answer (1 of 2): Why are global ... equivalent. In use the difference is name scope. Static variable names are only recognized with the module or function where they are declared - the address of the variable is unknown ...
Top answer
1 of 4
20

In a well-design C program, a file-static variable is similar to a private static member of a class:

  • It can only be accessed by functions in that file, similar to how a private static member variable can only be accessed by functions in the class in which it is defined.

  • There is only one copy of the variable.

  • Its lifetime is the program lifetime.

An extern variable would be a true global variable as in any language that supports them.

A static non-global variable is not as bad as a global; in fact, they are necessary in some cases.

  • Access is controlled through functions you write. This helps with data integrity including both bounds checking as well as thread-safety. (note: this does not guarantee thread-safety, it is simply one tool to help along the way)

  • Data is encapsulated: only that file can access it. This is as close as C can get to encapsulation where multiple functions can access a static variable.

Global variables are bad no matter what. Static file variables have the benefits of a private static variable but none of the drawbacks of a global variable.

The only issue is unlike with a true private static variable as in C++, other files can declare an extern variable matching the declaration and you cannot prevent access. In other words, you are relying on the honor system to avoid turning it into a global variable.

2 of 4
8

Global state, including extern variables and non-const static variables in file scope or in functions can frequently be an easy solution to a given problem, but there are three issues:

  1. static makes code untestable, because static variables tend to be non-replaceable dependencies. Or in more OOP-y words: you aren't following the Dependency Inversion Principle. I came to C and C++ from dynamic languages such as Perl, so my cost model is slanted towards virtual dispatch and function pointers and so on. With current languages, there's some conflict between testability and good architecture, but I think the minor nuisance of making your dependencies explicit and letting them be overridden in tests is noticeably offset by the ease of writing tests, and thus making sure your software is working as expected. Without making your code more dynamic, the only available mechanism to inject dependencies for a test is conditional compilation.

  2. Global state makes it difficult to reason about correctness, and that leads to bugs. The more bits and pieces have access to a variable and can modify it, the easier it is to lose track of what's happening. Instead: prefer single assignment of variables! Prefer const wherever reasonable! Prefer guarding variables through getters and setters where you can introduce correctness checks. As long as the state is static and not extern, it is still possible to maintain correctness, but it's always better to assume me-in-a-week won't be as smart as me-right-now. Especially in C++, we can use classes to model various abstractions that make it impossible to misuse something, so try to utilize the type system rather than your intelligence – you have more important stuff to think about.

  3. Global state might imply that your functions are not re-entrant, or that they can only be used in one context at a time. Imagine a database driver that could only manage one connection! That's a totally unnecessary restrictions. In reality, the limitations are often subtler, such as a global variable that's used to aggregate results. Instead, make your data flow explicit and pass everything through function parameters. Again, C++ classes can make this more manageable.

Obviously, static const NAMED_CONSTANTS are OK. Using static inside of functions is a lot trickier: while it is useful for lazily initialized constants, it may be fairly untestable. A compromise is to separate calculating the initial value from the static variable, so that both parts can be tested separately.

In small, self-contained programs, all of this won't matter, and you can keep using static state to your hearts delight. But as you pass around 500 LOC or if you are writing a reusable library, you should really start thinking about good architecture and a good interface without unnecessary restrictions.