Global variables in a header file - c

I was just wondering if you declare a variable in a header file like this
const static int START = 0;
would that variable (START) be considered global?

If you define:
const static int START = 0;
at file scope, then START will have internal linkage and static duration due to static.
This means that each translation unit that includes the header will end up with a copy of the symbol and that each of them will live throughout the entire program.

Yes and no.
Lets say you add that definition into 'myvar.h' and then you include that header file into 'main.c' and 'other.c'
All functions in 'main.c' and 'other.c' will know about the defined variable --so in a way, it is global.
But in fact there will be two different variables with the same name. Changes made by functions in 'main.c' won't be visible by functions in 'other.c' and vice versa.
That's because static variables defined outside of functions are considered 'local to the compilation unit'.
On the other hand, if you just remove the 'static' keyword, the variable will be defined twice (once for each compilation unit in which the header file is included) and the linker will emit a 'duplicate symbol' error.

Related

Static storage class in header file

Can we include static variable in header files.
If yes,Can other files can access it ?
Can we include static function in header files and use it in another files.
Can we pass static variable as function arguments ?suppose some function is there in header file header.h :
fun(static int a,static int b)
You can declare static variable in header files but this variable scope will only be that *.c file in which this header file will be included.
Any name declared in the global namespace with specifier static has internal linkage. This means that the name is visible within the translation unit where it is declared.
So if a header with a declaration of a name with static keyword is included in several translation units then each translation unit will have its own variable with such a name.
This is incorrect coding practice to use static variable in header files.
Also static limits the scope of variable to a file. So, static variable of file1.c can't be accessed from file2.c
A static variable can be defined in the header file. But doing so, the result will be having a private copy of that variable in each source file which includes the header file. So it will be wise not to declare a static variable in header file, unless you are dealing with a different scenario.
Same applies for static function.
Trying to apply static to a function argument doesn't make much sense, so the standard doesn't allow it (ยง6.7.5.3/2: "The only storage-class specifier that shall occur in a parameter declaration is register.")
trying to enter static variable as an argument type results in error.

Unused function warning

I have method in header file to which I added static keyword. e.g.
static int32_t Tlvlist_AddRawt(Tlvlist *a, uint8_t type, uint16_t size, const void *bytes);
The method is implemented in .c file where the static
keyword is not present in function name.
This method is called from another function of same .c file.
The later function (which uses this static function) is also called from main.
But I get warning: "Unused function 'Tlvlist_AddRawt'" in the header file.
Why would this happen?
ps. I use Xcode.
When you mark a function declaration static, it is not visible outside the translation unit in which it appears. But also, it represents a different function in every translation unit in which it appears. As such, it is rarely a good idea to use static in a header file, because then you're declaring a separate function in each C source that includes the header.
The compiler diagnostic is telling you that there is at least one C file that includes your header but does not provide a definition of Tlvlist_AddRawt() to go with the declaration from the header.
If you want to declare a static function separately from its definition -- for instance to prototype it for other functions that appear earlier in the source file -- then put the declaration in at the top of the C source file in which its body appears instead of in a header. Putting it in a header is counterproductive.
You never declare static functions in a header file intended for use in other modules, because the purpose behind making a function static is "hiding" it from users outside your modules. Static C functions are visible only inside the translation unit* where they are defined. When a function is declared static, but no other functions from the same translation unit use it, you get the "unused static" warning.
If you would like to define a function in one file, and use it from another file, you need to put its forward declaration in a header, include that header from both translation units, and link the translation results together. Removing the static keyword from the header should address this problem.
* Translation Unit is a fancy name for a .c file.

Odd C behavior: variable visible when it shouldn't be

In my program, I have a file called constants.h that declares the following matrix in a global scope (the matrix should be fully constant - if anyone sees a potential problem, let me know):
static unsigned char const MY_MATRIX[66][9] = {...};
In another file, let's call it main.c, I can actually reference this constant:
doSomething(var1, count, MY_MATRIX[42], TRUE, FALSE, thing);
But then I just read the definition of the keyword static and it's supposed to mean that the variable cannot be accessed outside the file it's defined in. (In this case, the desired behavior is that it should be accessed, but then it seems the extern keyword is the one to use!)
So, can anyone tell me why this works? Why is the variable not invisible? Thanks!
This is because you are declaring a static variable in a header: when you include the header in a C file, you get a brand-new definition independent of the other definitions. If you include the header in two files, you get two independent copies; if you include it in three C files, you get three independent copies, and so on. The copies do not conflict with each other, because the static definition hides them from the linker.
A proper way to make use of a shared piece of data allocated in a static memory is to make the declaration extern in the header, and then add a non-static definition in exactly one C file.
If it's in a header, it's defined in every single source file you include it in (though each source file will have their own instantiation of it - they don't access the same one).
There are two uses of the static keyword:
A static variable inside a function block keeps its value between subsequent calls.
A static global variable or a function is "visible" only in the file it has been declared in.
Here, you define the matrix in a header file, hence it is visible to all the .c files which include that header file. To restrict its visibility, define it in a .c file instead.
Usually when a static variable is declared in a header file its scope is not limited to .h file meaning nothing like header file scope. The translation unit includes the text from header file in source file. Therefore every translation unit including header file gets its own individual variable though it is static scope.

Just want to make sure I'm understanding what an external variable is

For our assignment we have to code a program in C, but it says not to use external variables in the program. Does this mean variables in other files brought into the main code, or am I unable to use variables in the same file if they're not in the same function? (ie: could I pass a value into a function as an argument and have it return a value that may have to do with a variable in that function and set the return value equal to something, or is that using external variables?)
I've Googled around but it's not exactly clear, and I want to make sure, as this is rather important.
Just to be sure, I'd make all my variables part of a function, and either pass them as parameters or return them from the functions.
There are at least two interpretations of external variables.
First off, we have the extern keyword, which basically symbolizes what you would call a global variable. It's a variable declared in multiple translation unit, but it only exists in one place in memory. It is initialized in a single file and all subsequent changes affect every scope the variable is used in:
//globals.cpp
int x = 1337;
//main.cpp
extern int x;
int main()
{
//x is 1337 here
return 0;
}
The second meaning could be a variable that is declared and defined in class scope, but not used as extern. However, you could consider it external to the methods.
//main.cpp
int x = 1337; //is this external?
//could be, remove it just to be safe
int main()
{
return 0;
}
Let's go with all the possible cases, because from your question I'm not too sure either:
There is extern as a keyword. In order to understand this, you need to understand compilation units. Basically, each file is a compilation unit - so each .c is compiled to a .o with the headers substituted in place. In each compilation unit, you forward declare symbols you expect to use - functions belonging to other compilation units, for example.
Now, if you declare a global variable in one .c file, it is global wrt that file, but does not exist as a symbol in any other file at all - the compiler will error because it doesn't know where that variable was declared.
(Of course, if you declare the variable in a header - it will exist in all of the objects the header is included in, and then the linker will sulk, because when it links all the objects up some of the symbols will have the same name).
To get around this, it is possible to define a variable with extern int x;, for example. This tells the compiler a) int x should be available to this compilation unit, b) int x is not in this compilation unit and c) the linker should check it exists somewhere in all the units you've put together to form a library or program.
Conceptually, you're doing this all the time with forward-declarations of functions. There's just no way to forward declare a variable. In fact, you can do this with functions too and not bother r.e shared headers, although this is not really a good idea.
The other case is that "external variables" mean something external to a certain scope or module you have. I would check your assignment very carefully and if in doubt ask - whoever set it should be able to explain to you exactly what they mean.
An external variable is a variable with external linkage.
A variable with external linkage is a variable defined at file scope without the static keyword.
int bla = 0; // external variable
static int blop = 1; // non-external variable
int main(void)
{
return bla
}
Note that a variable declared with the extern keyword doesn't necessarily have external linkage. Like const does not mean constant in C, extern does not mean external.
People often use the word external to say that a variable is actually declared in the current translation unit but is defined in another translation unit.

Internal linkage with static keyword in C

I know static is an overloaded keyword in C. Here, I'm only interested in its use as a keyword to enforce internal linkage.
If you have a global variable declared in a .c file, what is the difference between using static and not using static? Either way, no other .c file has access to the variable, so the variable is basically "private" to the file, with or without the static keyword.
For example, if I have a file foo.c, and I declare a global variable:
int x = 5;
That variable x is only available to code inside foo.c (unless of course I declare it in some shared header file with the extern keyword). But if I don't declare it in a header file, what would be the difference if I were to type:
static int x = 5.
Either way, it seems x has internal linkage here. So I'm confused as to the purpose of static in this regard.
If you have a global variable declared in a .c file, what is the difference between using static and not using static? Either way, no other .c file has access to the variable [...]
A different file could declare x:
extern int x;
That would allow code referencing x to compile, and the linker would then happily link those references to any x it finds.
static prevents this by preventing x from being visible outside of its translation unit.
There is only one "namespace", so to speak, in C. Without the "static" keyword you are not protected from another file using the name "x" (even if you do not make it visible in your own library's header).
Try to link together several C files containing a non-static variable x (interleaving read and write accesses from functions in each file), and compare with the situation where these variables are declared static.

Resources