My understanding is that a local static variable has "program scope"; that is, once defined it lives until the program terminates. Furthermore, my understanding is that local statics are also accessible outside the current module/C-file they are defined inside of:
void doSomething() {
static int myVar = 5; // Program scope & accessible to other modules
}
My understanding is that global static variables also have program scope, but that they are only visible to the current module/C-file:
static int myVar = 5; // Program scope but "module private"
void doSomething() {
// Whatever here...
}
Isn't this a bit backwards? I would have expected it to be the other way around. So I ask: is my understanding above correct? If so, then what is the motivation for local statics to be accessible outside their current module, but not global statics?
You messed up all. Static local variable is a place to hide data from other functions but retain data for future calls of that function.
Static global variables have
static storage duration (Retain data for future call)
internal linkage (variable is restricted to single file) and
file scope (Only in the current file the variable can be referenced)
Static local variables have
static storage duration
no linkage
block scope
Nope. Local Static variables are accessible with in given module.
While Global static variables are accessible with in given C-file.
Local static variable has limited scope to the function only.As you can see, following code gives compilation error because it tries to access "prox" variable from main even though it is static.
int main(void)
{
test();
printf("The PROX is : %d", prox);
}
test()
{
static prox;
prox=prox+5;
printf("INSIDE prox[%d]",prox);
}
Related
My script has an asynchronous conversation that polls a queue for new messages, while the user performs other tasks. I've put the web_reg_async_attributes() into init, my callbacks are in asynccallbacks.c, and my main logic is in action.c
The async polls every 5s, checking the message queue. When there is a message, I would like the callback to set a flag that the action.c has access to so that it can execute logic conditionally. I've tried using a global variable, declared in init, but it is not visible in asynccallbacks.c.
Is there a way to accomplish this? (I don't want to use files because I'm measuring activities that take less than a second and if I put the file system into the picture, my response times won't be representative).
In the first file (asynccallbacks.h) :
// Explicit definition, this actually allocates
// as well as describing
int Global_Variable;
// Function prototype (declaration), assumes
// defined elsewhere, normally from include file.
void SomeFunction(void);
int main(void) {
Global_Variable = 1;
SomeFunction();
return 0;
}
In the second file (action.c) :
// Implicit declaration, this only describes and
// assumes allocated elsewhere, normally from include
extern int Global_Variable;
// Function header (definition)
void SomeFunction(void) {
++Global_Variable;
}
In this example, the variable Global_Variable is defined in asynccallbacks.h. In order to utilize the same variable in action.h, it must be declared. Regardless of the number of files, a global variable is only defined once; however, it must be declared in any file outside of the one containing the definition.
I know its basic but I am not familiar with C and I couldn't understand the answers here in the subject .
Inside a C file I have this functions :
void uart_event_handle(app_uart_evt_t * p_event)
{
}
static void uart_init(void)
{
}
void initialize()
{
uart_init();
}
The static function uart_init() was inside some example program main.c , i am trying to put it inside another C file ( this one)
The error occurs only when I call : uart_init(); . Otherwise it will not happen.
Declaring a function static makes it invisible outside the translation unit. This is similar to declaring fields private in a class, because static "hides" the function from all other files.
This lets you define a new function with the same name in some other file without worrying about name collisions. At the same time, static makes it impossible to call the function from outside the .c file where it is defined.
Your example provides a use case for making static functions: initialize becomes part of the "public" interface of the library, while uart_init remains hidden.
Update static variable outside of the file without modifying the file in which the static variable is declared in C lang.
Proj1 creates dll. Proj1 has abc.h file and it is defined as below :
static BOOl stvar = False;//declared as global static variable
func1()
{
stvar= TRUE;
}
func2()
{
if(stvar == TRUE)
{
....
}
else
{
func1(); //call to func1 sets STVAR = TRUE;
}
}
Proj2 Creates exe. It has cprog1.c file. cprog1.c file is defined as follows:
cprogfunc1()
{
func2(); //call to func2 sets STVAR = TRUE;
}
cprogfunc2()
{
stvar = FALSE;
func2();
}
We are setting stvar to false in cprogfunc2() to make it execute else block in func2() of abc.h file. But the value we set in cprogfunc2() under cprog1.c is not reflected in abc.h file. We are updating static variable outside its declaration because we cannot modify anything under proj1. So please suggest some ways to update static variable from cprog1.c file without modifying abc.h/Proj1. If that is not possible suggest any workaround. Thanks.
Solutions already tried :
Making stvar non static - not possible since we can not modify abc.h file
Using pointers - did not work
By definition, stvar was made static in order to limit accessibility to it, meaning the ideal way to tinker with it from the outside is to create an API for it (or indeed make it global, not static). Since editing Proj1 is out of the question, we are left with a bad situation.
What you could do is to reset Proj1's state by freeing the dll and loading it again, as mention here.
I am looking at a crash dump, and an important clue to how this crash occurred may be inside the value of a static variable (an integer in this case) inside a function. The problem is that the function with that static variable is is not in my call stack where the crash occurred so I can't just look at it directly. Is there a way to view the contents of this variable from the debugger from outside the function that declares it?
Edit:
Sample code has been requested
int funcitonWithStaticVar()
{
static int iRetVal;
if (iRetVal == 0)
{
iRetVal = initializeValue();
}
return iRetVal
}
void functionThatCrashes()
{
// Crash occurs in this function. The
// static variable in the other function
// may hold an important clue as to why
}
int foo()
{
functionWithStaticVar();
functionThatCrashes();
}
You can determine the address of the static variable by viewing the disassembly of the function that accesses it.
EDIT: this is a rewrite of the question since it was so unspecific before.
So I'm having a problem solving the issue of variables being shared across instances in C extensions. Here is an example of what I'm encountering.
>> t = SCOPE::TestClass.new #=> #<SCOPE::TestClass:0x000001011e86e0>
>> t.set = 4 #=> 4
>> t.get #=> 4
>> v = SCOPE::TestClass.new #=> #<SCOPE::TestClass:0x00000101412bf0>
>> v.set = 5 #=> 5
>> v.get #=> 5
>> t.get #=> 5
Would the best solution in the code below be to simply use ruby variables that you can set up like
void rb_define_variable(const char *name, VALUE *var)
Or is there a solution in C that I'm not seeing or understanding?
Code:
#include <stdlib.h>
#include <ruby.h>
VALUE TestClass;
VALUE SCOPE;
VALUE test_var;
VALUE set(self, val);
VALUE get();
VALUE set(VALUE self, VALUE val) {
test_var = NUM2INT(val);
return Qnil;
}
VALUE get() {
return INT2NUM(test_var);
}
void Init_scope()
{
SCOPE = rb_define_module("SCOPE");
TestClass = rb_define_class_under(SCOPE, "TestClass", rb_cObject);
rb_define_method(TestClass, "set=", set, 1);
rb_define_method(TestClass, "get", get, 0);
}
Ok, now I think I see the problem. Your
VALUE test_var;
is a sort of "shared" value among every instance of the test class. This is an error of course, since it is overwritten as new instances are created or method set is called. So you can have just a single instance and a value shared among every instance.
Of course you are doing something wrong: ruby has to provide context and a way to retrieve it, likely the proto for the get function must have at least VALUE self as argument, like set. The value can't be stored into global or static local variable: it must be someway stored into the "context" of the object. In order to know how to do so, I need a fast tutorial about ruby ext. In the meantime try to read deeper here.
In particular, focus your attention on "Accessing Variables" and how you define instance variables.
I have done this, that seems to work; you could like to work on it to achieve your extension purpose(s) (I've renamed something, and fixed something else; I've also removed the INT2NUM and NUM2INT stuff, you can put it back at your need)
#include <stdlib.h>
#include <ruby.h>
VALUE TestClass;
VALUE SCOPE;
VALUE set(VALUE, VALUE);
VALUE get(VALUE);
VALUE set(VALUE self, VALUE val) {
(void)rb_iv_set(self, "#val", val);
return Qnil;
}
VALUE get(VALUE self) {
return rb_iv_get(self, "#val");
}
void Init_RubyTest()
{
SCOPE = rb_define_module("RubyTest");
TestClass = rb_define_class_under(SCOPE, "TestClass", rb_cObject);
rb_define_method(TestClass, "set=", set, 1);
rb_define_method(TestClass, "get", get, 0);
}
This question can't be answered fully if we don't know how "C extension" (I suppose, to Ruby?) works, and sincerely I don't know.
A "global" variable declared static is local to the file where it is defined and can't be accessed from outside, i.e. it is global inside that file, but it is not a global for all the linked files.
func1 can access bar, indeed; it can't just because the symbol is not known until it is declared (for the same reason func1 can't call func2, or at least compiler gives a warning for the missing prototype, then the code to func2 will be found anyway), but anyway, once the symbol is known, it can be accessed. On the contrary, those variables bar and foo can't be seen from outside (and so are not global) since the symbols foo and bar are not visible.
If this code is supposed to be compiled as a shared object or a static library, foo and bar won't be visible by the code that links the shared object / static library.
Global variables are according to the specification of ruby c extensions shared amongst each other (see documentation). It is the best option to limit variable scopes to the least visible which does the job. If you happen to have a shared variable it should be at least safe to synchronization issues.