Initialization for static variables - c

static int i = 5;
static int j = i;
int main()
{
return 0;
}
I am initializing the static variable by another static variable which is declared before that but also I am getting variable. Please tell me why this is error.

You cannot initialize j with i, because at compile time, compiler will not know the value of i.To assign the value j = i, the code need to be executed at run time. When initialize the global or static in C, the compiler and linker need to work together to create the layout of memory. Compiler will give the value and linker need to give the address of the variable.
The below code will work:
static int i = 5;
static int j;
int main()
{
j=i;
return 0;
}

If this is a real case, you maybe should initialize them explicit.

Related

C static variables initialization

I learned some C and came across an explanation for static variables.
They showed this code:
#include<stdio.h>
int fun()
{
static int count = 0;
count++;
return count;
}
int main()
{
printf("%d ", fun());
printf("%d ", fun());
return 0;
}
I can't understand why calling the function twice is fine, because the line
static int count = 0;
actually runs twice...
I can't understand how is that possible...
Can you actually declare it twice or does the compiler just ignore it the second time?
This (statics/globals) is where an initializing definition is really different from an uninitialized definition followed by an assignment.
Historically, the former even used to have different syntax (int count /*no '=' here*/ 0;).
When you do:
int fun() {
static int count = 0;
//...
}
then except for the different scopes (but not lifetimes) of count, it's equivalent to:
static int count = 0; //wider scope, same lifetime
int fun() {
//...
}
In both cases, the static variable becomes initialized at load time, typically en-masse with other statics and globals in the executable.
static variables are initialized on program startup, not every time the function is called.
... because the line static int count = 0; actually runs twice.
No. Just once, right before main() is called.

C static scope variable undefined

My goal is to add (without modifying any of the existing code) a function retrieve() which returns the current value of the counter.
#include <stdio.h>
void increment(void){
static unsigned int counter = 0;
counter++;
printf("%d\n", counter);
}
int main(void){
for (int i = 0; i < 5; i++){
increment();
}
printf("counter = %d\n", retrieve());
return 0;
}
However, everything I try is running into a scope issue. Namely that counter has not yet been instantiated yet so the compiler considers it to be an undefined name. I've tried adding a function
int retrieve(void){
return counter;
}
between increment and main and also within both increment and main themselves. My understanding of the static keyword is that once the variable is instantiated it will persist beyond the block it is defined in for the length of the program execution. So I think the issue I'm running into is that the variable is not yet instantiated. Any help would be great.
Scope and lifetime are two different things, and they're partly independent.
Scope is the region of program text in which an identifier is visible.
Lifetime (or storage duration) is the duration during program execution in which an object exists.
The object named counter, because it's defined with static, has static storage duration, which means that it exists during the entire execution of the program. But the identifier counter has block scope, which means that the name is visible only from its declaration to the } that terminates the innermost block in which it's declared. (In this case, that block happens to be the outermost block of a function definition.)
you need to move counter into global scope
#include <stdio.h>
static unsigned int counter = 0; <<<=========
void increment(void){
counter++;
printf("%d\n", counter);
}
int retrieve(void){
return counter;
}
int main(void){
for (int i = 0; i < 5; i++){
increment();
}
printf("counter = %d\n", retrieve());
return 0;
}
accepted best practice is to indicate in the name that its global
unsigned int COUNTER = 0;
or
unsigned int g_counter = 0;

Initialising a static const variable from a function in c

I have recently run into some trouble while trying to perform the following logic:
static const int size = getSize();
int getSize() {
return 50;
}
The error I have received is initialiser element is not constant
Having read online I understand that this issue is because the compiler evaluates the static const expression at compilation and therefore cannot know what the value is supposed to be.
My question is how do I get around this?
If I have a library that contains many functions but they all require this logic how are they supposed to use it without having to calculate it each time?
And even if they have to, what if the logic itself can change throughout runtime but I only ever want the first value I receive from the function?
Perhaps I should clarify that the logic in getSize is just an example, it could also contain logic that retrieves the file size from a specific file.
Unlike in C++ you cannot initialize global variables with the result of a function in C, but only with real constants known at compile time.
You need to write:
static const int size = 50;
If the constant must be computed by a function you can do this:
Dont declare static const int size = ... anymore, but write this:
int getSize()
{
static int initialized;
static int size;
if (!initialized)
{
size = SomeComplexFunctionOfYours();
initialized = 1;
}
return size;
}
int main(void)
{
...
int somevar = getSize();
...
That way SomeComplexFunctionOfYours() will be called only once upon the first invocation of getSize(). There is a small price to be paid: each time you invoke getSize(), a test needs to be performed.
Or you can initialize it explicitely like this, but then size cannot be const anymore:
static int size;
void InitializeConstants()
{
size = SomeComplexFunctionOfYours();
}
int main(void)
{
InitializeConstants();
...
int somevar = size;
...
The compiler needs to know the value of your constant variable at the compilation time, because its a constant.
Also you can't initialize a variable with a function.
You should do something like this :
#define SIZE 50
static const int size = SIZE;

Local variable and static variables

I just want to understand the difference in RAM allocation.
Why if i define a variable before function i have a RAM overflow and when i define it inside a function it is ok?
For example:
/*RAM OK*/
void Record(int16_t* current, int i,int n)
{
float Arr[NLOG2] = {0};
for(i=0;i<n;i++)
Arr[i]=current[i*5];
}
/*RAM OVERFLOW*/
static float Arr[NLOG2] = {0};
void Record(int16_t* current, int i,int n)
{
for(i=0;i<n;i++)
Arr[i]=current[i*5];
}
This is the message:
unable to allocate space for sections/blocks with a total estimated
minimum size of 0x330b bytes (max align 0x8) in
<[0x200000c8-0x200031ff]> (total uncommitted space 0x2f38).
The difference is that in the first case, Arr is declared on the stack; until the function is called, that array doesn't exist. The generated binary contains code for creating the array, but the array itself isn't in the binary.
In the second case, however, Arr is declared outside of any function (aka at file scope). Therefore, it always exists, and is stored in the binary. Because you appear to be working on an embedded platform, this otherwise insignificant difference causes your "RAM overflow" error.
In the 2nd case, the array is allocated when the application starts. It remains in the memory until the app quits.
In the 1st case, the array is only allocated when function void Record(int16_t* current, int i,int n) is called. The array is gone after the function finishes its execution.
static keyword doesn't have any impact if you have only a single compilation unit (.o file).
Global variables (not static) are there when you create the .o file available to the linker for use in other files. Therefore, if you have two files like this, you get name collision on a:
a.c:
#include <stdio.h>
int a;
int compute(void);
int main()
{
a = 1;
printf("%d %d\n", a, compute());
return 0;
}
b.c:
int a;
int compute(void)
{
a = 0;
return a;
}
because the linker doesn't know which of the global as to use.
However, when you define static globals, you are telling the compiler to keep the variable only for that file and don't let the linker know about it. So if you add static (in the definition of a) to the two sample codes I wrote, you won't get name collisions simply because the linker doesn't even know there is an a in either of the files:
a.c:
#include <stdio.h>
static int a;
int compute(void);
int main()
{
a = 1;
printf("%d %d\n", a, compute());
return 0;
}
b.c:
static int a;
int compute(void)
{
a = 0;
return a;
}
This means that each file works with its own a without knowing about the other ones.

Global variable does not take new value

I was making a simple C program
#include<stdio.h>
static int a;
a = 5;
int main()
{
printf("%d",a);
return 0;
}
Compiler error: "non static declaration of 'a' follows static declaration"
What does this error mean?
what this error log means?
It is a little tricky: what looks like an assignment
a = 5;
is treated as
int a = 5;
due to an old C rule that allowed you to declare int variables and int-returning functions without specifying their type explicitly (this is definitely not a good idea in the modern version of C).
Note that this is treated as a declaration with an implicit int only in the scope outside a function body.
You can fix it by combining the declaration with initialization, like this:
static int a = 5;
Outside a function you can only declare variables, you cannot have actual code statements.
a = 5;
is being interpreted as another declaration, when your intent I think is to write some code.
instead declare and initialise a at the same time
static int a = 5;
Your first declaration of a is static (ahas internal linkage).
The second declaration is not static (a has external linkage). Yes, a = 5; is a declaration with implicit type int in this case.
Both do not agree.
Btw. for functions this would be o.k. because the second declaration would "inherit" the internal linkage.
We cannot write any assignment statement globally. For example:
#include <stdio.h>
static int i=10; //Initialization statement
i=25; //Assignment statement
int main(){
printf("%d",i);
return 0;
}
Output: Compilation error
Note: Assigning any value to the variable at the time of declaration is known as initialization while assigning any value to variable not at the time of declaration is known assignment.
You can't set value as you did it: a = 5; before main(...). See code below:
static int a = 1; //default = 0;
int main()
{
printf("a = %d\n", a);
a = 2;
printf("a = %d\n", a);
return 0;
}
Output:
a = 1
a = 2
A = 5 is considered as an attempt to create another variable called a. You should put the = 5 after static int a.
Static int a = 5;
Just a little modification to your code will help you to understand it.
#include<stdio.h>
//static int a; //comment this statement
a = 5;
int main()
{
printf("%d",a);
return 0;
}
now compile this code [please enable your compiler's warnings]
Then you will get a warning something like this
data definition has no type or storage class [enabled by default]
So now try to understand this warning it means that compiler treat statement a=5 as a definition but without data type. But compiler unable default data type that is int.
so this statement is equivalent to
int a=5;

Resources