Reputation: 105
So I was playing about trying to understand the use of static variables, clearly my understanding is not quite there yet as I don't understand how the following is operating:
Main calling my useful function that spits outs the contents of x and y from other.c
//main.c
#include <stdio.h>
#include <stdint.h>
#include "other.h"
int main (void)
{
printf("Main - X: %d, Y: %d\r\n\n",x,y);
func();
printf("Main - X: %d, Y: %d\r\n\n",x,y);
func();
printf("Main - X: %d, Y: %d\r\n\n",x,y);
printf("Main - X: %d, Y: %d\r\n\n",++x,++y);
return 0;
}
other.h
//other.h
void func(void);
uint8_t x;
static uint8_t y;
other.c
//other.c
#include <stdio.h>
#include <stdint.h>
#include "other.h"
void func(void)
{
x += 1;
y += 2;
printf("Func - X: %d Y: %d\r\n",x,y);
}
My output:
Main - X: 0, Y: 0
Func - X: 1 Y: 2
Main - X: 1, Y: 0
Func - X: 2 Y: 4
Main - X: 2, Y: 0
Main - X: 3, Y: 1
Two things I can't explain; Why is it that accessing y from main does not cause an warning/error? How/Where am I storing the values set to y when it is equal to 0 and 1 in main?
What should I do different if I want to cause issues by accidentally accessing static variables outside their scope?
Upvotes: 1
Views: 55
Reputation: 310920
According to the C Standard (6.9 External definitions)
5 An external definition is an external declaration that is also a definition of a function (other than an inline definition) or an object. If an identifier declared with external linkage is used in an expression (other than as part of the operand of a sizeof operator whose result is an integer constant), somewhere in the entire program there shall be exactly one external definition for the identifier; otherwise, there shall be no more than one.161)
However the compiler can not check whether an identifier with external linkage was defined more than one time. It is the linker that does such a check. So you should see options of the linker. Sometimes by default they simply eliminate superflouos definitions. However sometimes the behaviour becames undefined.
In general there are three possibilities. The first one is that the linker issues an error. The second one is that the linker keeps only one definition of the external object. The third one is that the linker makes all duplicates of the object with external linkage as objects with internal linkage.
In your case it seems the linker keeps only one definition of the object with name x.
As for variable y with internal linkage due to its declaration with keyword static then the two compilation units one with main and other with func have their own object y. So inside the first compilation unit that is in main you change one object y while function func in other compilation unit changes its own object y though there is an illusion that y is the same object.
Upvotes: 1
Reputation: 19864
When you have a static variable in a header file new object of it is created everytime you include it. The scope of it will be just for that module (or file). Since in one file(other.c
) you are incrementing it you are seeing the values are being incremented and in the other(main.c
) your not incrementing it hence the value is always 0.
Upvotes: 0