I recently came across the question like how to access a variable which declared static in file1.c to another file2.c?
Is it possible to access static variable?
My understanding about static keyword in C is,
static is "internal linkage", so they are accessible only from one compilation unit - the one where they were defined. Objects declared with internal linkage are private to single module.
As one of my friend suggest me below solution.
In file1.c
#include <stdio.h>
int main()
{
int b=foo();
printf("%d",b);
return 0;
}
in file2.c
static int a=25;
int foo()
{
return a;
}
compiled by gcc file1.c file2.c -o file
If I do above I can access the variable.
So my questions are:
Does the above program violate static variable rules?
If not, why is this so, and is there any other way to access static variable except including file (#include <…>) not like this.
How am I able to access a static variable from another file?
In C, how do I restrict the scope of a global variable to the file in which it's declared?
Correct me if I'm wrong with static variable concept and if any better solutions are available to access static variable?
1) does the above program violate static variable rules?
No you are not vailoting any rules. Here foo function create copy of value of that static variable and used in other file. Its fine.
2) If not why is this so, and is there any other way to access static variable except including file (#include<>) not like this How am I able to access a static variable from another file?
Static variable are only mean to use in that file only.
You can not use that variable making them extern in other files.
Another dirty hack is to get pointer of that static variable and make that as global pointer and making that as extern in another file you can use that static variable.
file1.c
#include<stdio.h>
static int a=25;
int* ptr = &a;
file2.c
#include<stdio.h>
extern int *ptr;
int main()
{
printf("%d",*ptr);
return 0;
}
Correct me if I'm wrong with static variable concept and if any better solutions are available?
A static variable has a lifetime extends across the entire run of the program
If you do not initialize static variable with some value then its default value would be 0.
A static variable has scope limited to its file only. You can not access it by name from a different file.
You have temp1.c and temp2.c both are getting compiled together then also you can have static variable of same name in both files — and they are separate variables.
In C, how do I restrict the scope of a global variable to the file in which it's declared?
By making that global variable as static.
What we commonly call a variable in C is actually two things: an object, the memory allocated for the variable interpreted with a certain type, and an identifier, one way to access that object.
There is no problem in accessing a static object or its value from another compilation unit. Your function foo promotes the value to another unit, that is fine, but it could even promote the address of a without problems.
Having internal linkage only concerns the identifer, the name a. This one is only visible inside file2.c.
With the static int a=25; the variable a will have internal linkage; meaning the linker cannot see a anywhere outside of the file2.c TU.
When you're calling foo() in file2.c, you get a copy of a, it's the copy that you print; but this doesn't mean you have access to the actual a defined in file2.c When you need such an access where the same variable is visible across different TUs, you could do this
Defining file
This file both declares and defines the variable; additionally initializes it to 1 too, without which it'll be default initialized to 0.
// (non-static) global variable with external linkage and thus visible across TUs
int var_across = 0;
void use()
{
var_across = 1;
}
Using file
// just a declaration to tell that it's defined elsewhere; not a definition
extern int var_across;
void use_here()
{
var_across = 2;
}
Assigning address of static variable to pointer will make static variable available to subfiles.
In subfiles we have to use extern keyword to the pointer.
But it is not necessary to do that.
Related
I'm getting my sea legs with C, and I need a string literal which is discovered in a main function in one .c file to be accessible in an entirely different .c file.
What I've tried: I'm declaring a pointer to a string literal as extern in a header, defining it on one .c file, and trying to access the literal in a second .c file. Compilation is failing due to lack of definition in the second (accessing) file.
What I've got in a nutshell:
file1.h :
extern char *global;
file1.c :
#include "file1.h"
int main() {
//some code
extern char *global = some_struct->data;
//more code
}
file2.c :
#include "file1.h"
int do_stuff() {
//some code
some_function(global);
//more code
}
I expected this to compile, since global is declared in file1.h, defined in file1.c, and its value accessed in file2.c. Compilation of file2.c fails, however, for undefined variable.
If relevant, the main function in file1.c is always the first function run in the program.
in main
extern char *global = some_struct->data;
is wrong, if you want to assign global do :
global = some_struct->data;
and some where at global scope you need to define global :
char *global;
So for instance main become :
#include "file1.h"
char *global;
int main() {
//some code
global = some_struct->data;
//more code
}
You're close, but not quite there. The global variable must also be defined in the global scope, and you're running into the difference between declaration and definition (which are easy to get the wrong way round but the words don't matter as much as the idea). Normally, your statements that introduce a variable will both declare and define simultaneously, but not so with globals that are shared between modules like this:
In your file1.h, you are correctly declaring the char* variable in the global scope. Anyone who includes this file (e.g. file2.c) will "see" that the variable with that name should exist and all modules will compile cleanly, and the extern keyword makes explicit that you are only declaring this to exist, not creating storage for it yet. That is what you want, because you don't want to accidentally create multiple conflicting global variables with this name. When the compiled modules are eventually linked together, the linker will look for the actual memory storage space set aside for the global and connect all the references up correctly.
But in your case, that won't happen correctly, because although you have declared to the world that this global exists, you haven't yet actually created storage for the variable!
You still need to do this in the global scope (outside the functions) in file1.h:
char * global;
That creates the actual variable with the matching name to the extern declaration, and so the linker will be able to assemble your modules correctly.
So
#include "file1.h"
// Define global:
char * global;
int main() {
// Assign a value to the global variable:
global = some_struct->data;
//more code
}
Note that you don't redeclare the extern or anything in this file, and you don't redefine the type of global inside main, because it already exists, and you can assign to it or look at its value. You also don't use the keyword extern here-- it is the "home" module for this variable.
Declaration and definition are generally just accomplished simultaneously, for example when you declare local variables within a function. Globals that are accessible from different modules rely on splitting the work into the two separate ideas so that both coworkers and the compiler and linker toolchain are not confused by your intentions.
I am not very much familiar with modular structure of C programming, so I decided to ask you for help.
Let pretend I have two modules into the project. The one is sx1272.c and the other is sx1272_ll.c. The variable radio_is_on is declared in sx1272_ll.c as follows:
static uint8_t volatile radio_is_on;
and then accessed by function in sx1272.c like this:
foo(){
...............
if(radio_is_on){
blablabla...
............
}
...............
}
So if radio_is_on is static (in module scope) how come it is accessed by other modules?
sx1272_ll.c
sx1272.c
It seems to me that you included
#include "sx1272_ll.c"
in you your source file sx1272.c
So the whole content of file sx1272_ll.c is just copy-pasted into sx1272.c, at the position where you have written #include "sx1272_ll.c" during the pre-proccesing stage.
Refer this link: https://en.wikipedia.org/wiki/C_preprocessor#Including_files
you cannot declare variable static and access it from another module.
static has 3 usages:
1) if variable declared static whithin block (eg. function) it will maintial it's value during invocations.
int add(void){
static int var = 0;
var++;
return var;
}
int main(void){
printf("Var = %d", add()); // Here var = 1
printf("Var = %d", add()); // Here var = 2
return 0;
}
2) if variable declared static in a file, it can be accessed only within this file and no other file can access it.
If we declare
static uint8_t volatile radio_is_on; in file X, it will not be accessible in file Y.
3) if function declared static in a file, it can be accessed only within this file and no other file can access it.
The static keyword outside any function means, that variable (more strictly object represented by that variable) has internal linkage, which you can think as it is more or less private to that module, where it is defined. There would be no symbol generated in object file for such variable (you could inspect it with tools like nm or readelf).
You might either define it with external linkage by omitting static (optionally adding extern keyword), or if you need it to be static for some special reason (?), then write wrapper function, that exposes it into other module. It might be defined as:
sx1272_ll.c:
static uint8_t volatile radio_is_on;
uint8_t volatile *get_radio_is_on(void)
{
return &radio_is_on;
}
then put prototype into:
sx1272.c:
uint8_t volatile *get_radio_is_on(void);
There is no risk, that such pointer would point into invalid memory region, because file-scope variables have static storage duration, that means lifetime of whole application.
In the strictest sense its not possible to access static variables from other modules, that's exactly what the keyword is intended for.
But one way to do it is to add an external function is_radio_on() which returns its value.
K&R c page 83 says the following:
The static declaration, applied to an external variable or function, limits the scope of that object to the rest of the source file being compiled. External static thus provides a way to hide names like buf and bufp in the getch-ungetch combination, which must be external so they can be shared, yet which should not be visible to users of getch and ungetch.
How could any external variable be visible in another file without an extern modifier on the variable in the new file anyway? Is there some type of added protection for variables with the static storage class?
What is the purpose of using static on an external variable? Any simple examples?
Edit:
I think I'm confusing people with my question, so I'm going to write it out as code. I'm expanding the idea to include functions as well:
contents of file 1
void somefunc(void);
int x;
int main()
{
....
}
void somefunc(void)
{
....
}
file 2
int x;
void somefunc(void);
void somefunc(void)
{
....
}
Notice that int x and somefunc() in file 1 are not visible in file 2, and vice versa. That is, unless we include an extern modifier on int x and/or somefunc() in either file, the matching function and variable names from the files will be invisible to one another.
Why would we need to put static on one of these variables or functions to prevent the variable or function from being visible in the other file if we already have to knowingly use an extern to make the function or variable visible in the other file?
The code would need to look like this for contents of file 2 to be visible in file 1:
extern void somefunc(void);
extern int x;
int main()
{
....
}
void somefunc(void)
{
....
}
file 2
int x;
void somefunc(void);
void somefunc(void)
{
....
}
There is a difference of terminology between K&R2 and the C Standard.
K&R2 uses the wording external variable for a file-scope variable, and uses the wording external static to specify a file-scope variable declared with the static storage class specifier. In the C Standard the word external is usually reserved for linkage and not for lexical scope.
Quoting what you quoted:
External static thus provides a way to hide names like buf and bufp in the getch-ungetch combination, which must be external so they can be shared, yet which should not be visible to users of getch and ungetch.
It just means that the static variables are not function scoped static variables. They are external to functions but they are static in the file.
Making them static in a file makes them visible to getch and ungetch but not to other functions in other files.
Update, in response to edited question
You said,
Notice that int x and somefunc() in file 1 are not visible in file 2, and vice versa. That is, unless we include an extern modifier on int x and/or somefunc() in either file, the matching function and variable names from the files will be invisible to one another.
That is an erroneous conclusion.
The line
int x;
equivalent to:
extern int x;
int x;
The line
void somefunc(void);
is equivalent to:
extern void somefunc(void);
If you compile the "file 1" and "file 2" and link the resulting object files to create an executable, you will get linker errors to the effect that int x and void somefunc(void) are multiply defined.
In order to keep them visible only in the respective files, you will have to make them static in the file scope.
static int x;
static void somefunc(void);
What are the uses of the keyword static?
This simple question is rarely answered completely. Static has three distinct uses in C:
(a) A variable declared static within the body of a function maintains its value between function invocations.
(b) A variable declared static within a module1, (but outside the body of a function) is accessible by all functions within that module. It is not accessible by functions within any other module. That is, it is a localized global.
(c) Functions declared static within a module may only be called by other functions within that module. That is, the scope of the function is localized to the module within which it is declared.
Most candidates get the first part correct. A reasonable number get the second part correct, while a pitiful number understand answer (c).
From A ‘C’ Test: The 0×10 Best Questions for Would-be Embedded Programmers
Think about such a situation:
If you have three files, file1 and file 2 both have int x, but with different values, then in file3 you have extern int x. How could the compiler know which x you want? That's when you need extern.
Here's my code:
File DataTypes.h
static int count=0;
File TreeOps.h
#include"DataTypes.h"
void printTree(Tree* ptr)
File TreeOps.c
#include"TreeOps.h"
void printTree(pointer){
count++; // incrementing the count;
printf("%d",counter);
}
File TreeMain.c
#include"TreeOps.h"
printTree(pointer); // all the necessary declarations are done.
printf("%d",count);
If in printTree function the printf gives count=1; while in main function it gives me 0.
Why?
static variable in this context means: every c file has its own variable instance. Remove static definition in h-file:
extern int count;
and add this to one of c files:
int count = 0;
extern means: this is forward declaration. By defining a variable as extern, you tell to compiler that count has int type, and this variable is created somewhere. Actually, this variable is created in one and only one c file. You can use it in any c file where DataTypes.h is included. In the file where this variable is created, compiler uses it. In all other file this variable becomes external reference, which is resolved later by linker.
First off, defining data or functions in header files is a bad practice in C programming. In DataTypes.h you don't just declare the count variable, but you define it.
What actually happens is that the count is defined separately in each translation unit and you end up with two variables after linking. The linker doesn't merge them because they are marked static, that means they should be local to the translation unit.
If you want the count variable to be shared between the TreeOps.c and TreeMain.c translation units, you must use extern in the header file which only declares it:
extern int count;
And then define it globally as int count in either of TreeOps.c or TreeMain.c.
You don't have a "global static int" in your program. Entities declared as static cannot possibly be "global". The whole point of declaring something static is to make it local to a specific translation unit. This is exactly what you've done: you have declared two completely independent static variables in two different translation units. Each variable is local to its own translation unit. Then you are modifying one of these variables and printing the other. No wonder that the other remains unchanged.
In this case you have to decide what it is exactly you want. You can either have your variable as a global variable or as a static variable, but not both at the same time. "Global variable" and "static variable" are mutually exclusive concepts. So, what is it you want: global or static?
Is the static keyword in C used only for limiting the scope of a variable to a single file?
I need to know if I understood this right. Please assume the following 3 files,
file1.c
int a;
file2.c
int b;
file3.c
static int c;
Now, if the 3 files are compiled together, then the variables "a" & "b" should have a global scope and can be accessed from any of the 3 files. But, variable "c" being static, can only be accessed from file3.c, right?
Does static have any other use in C ? (other than to limit the scope of a variable as shown above?)
The static keyword serves two distinct purposes in C, what I call duration (the lifetime of an object) and visibility (where you can use an object from). Keep in mind the C standard actually uses different words for these two concepts but I've found in teaching the language that it's best to use everyday terms to begin with.
When used at file level (outside of any function), it controls visibility. The duration of variables defined at file level are already defined as being the entire duration of the program so you don't need static for that.
Static variables at file level are invisible to anything outside the translation unit (the linker can't see it).
When used at function level (inside a function), it controls duration. That's because the visibility is already defined as being local to that function.
In that case, the duration of the variable is the entire duration of the program and the value is maintained between invocations of the function.
You are misusing the term "scope". static in C has absolutely nothing to do with scope.
Scope is the region where the name of an entity (variable, function, typename etc.) is visible. In C language "file scope" is the largest scope ever. For that reason, there's no point in limiting anything to a single file: there's simply nothing larger to limit. There's no such thing as "global scope" in C. The term "global scope" is sometimes used informally, but in that case it has the same meaning as "file scope".
Again, static in C has absolutely nothing to do with scope. static in C affects storage duration of an object and linkage of an identifier. When used with objects (variables) static gives the object static storage duration (i.e. the object exists as long as the program runs). And, when used with identifiers of non-local objects or functions, it gives them internal linkage, meaning that the same identifier refers to the same entity within a single translation unit (where the entity is defined), but not in other translation units.
static is also used within a function definition to define a variable which keeps its value between function calls. I found an example here. In contrast, variables which are created anew with each function call are called automatic.
An example to augment Kinopiko’s answer:
#include <stdio.h>
int foo() {
static int foo = 0;
return ++foo;
}
int main() {
printf("%i\n", foo()); // 1
printf("%i\n", foo()); // 2
}
This can be used for example to return a safe pointer to a local function variable. Or in Objective-C it’s sometimes used to guard against repeated class initialization:
- (void) initialize
{
static BOOL initialized = NO;
if (initialized)
return;
// …perform initialization…
initialized = YES;
}
A variable may have three kinds of storage:
In program's Static Area
On stack (during function call)
On Heap (when you allocate using new/malloc)
Global variables are always stored in static area. But to store a local variable in static area, you need the keyword static. As a static variable is not allocated on stack, you can access the variable on subsequent calls.
Also static keyword at global scope gives a variable internal linkage.Consequently the variable cannot be accessed from some other file using the extern qualifier.
You are correct, this is called "static linkage": The symbol declared as static is only available in the compilation unit where it is defined.
The other use of static would be inside a function:
void f() {
static int counter = 0;
counter++;
// ...
}
In this case the variable is only initialized once and keeps it's value through different calls of that function, like it would be a global variable. In this example the counter variable counts the number of times the function was called.
internal linkage vs external linkage by example
//file1.c
#include <stdio.h>
int glb_var=3;//global variable
int func(); //prototype of function
int main()
{
func();
func();
func();
return 0;
}
int func()
{
static int counter=0;//static varible
printf("val of counter=%d",counter);
counter+=5;
return 0;
}
when we will compile this program and run this program then os will load this program in memory.then below things will happened:
glb_var identifier will be stored in initialized data segment.
counter identifier will be stored in uninitialized data segment called ".bss".
static variable initialized once and the values persists during function calls.because static variable is stored in data segment not in stack so static variable persist during function calls.
So output of the program will be:
0 5 10
one important thing about static variable is that it has internal linkage.so we can access this variable to a particular file.In which they are defined (not in other file).
We can access global variable glb_var in other file by using extern keyword.
for eg:
//file2.c
#include <stdio.h>
extern glb_var; //for declaration of this variable
int main()
{
if(glb_var)
{
printf("glb_var=%d",glb_var);
}
}
output: 3
this is called external linkage.