Definition of global variables using a non constant initializer - c

#include <stdio.h>
int i=10;
int j=i;
int main()
{
printf("%d",j);
}
I get an error stating that initialization element is not a constant? What is the reason behind this?

What is the reason behind this?
C(unlike C++) does not allow initialization of global values with non constant values.
C99 Standard: Section 6.7.8:
All the expressions in an initializer for an object that has static storage duration shall be constant expressions or string literals.

You could try using:
int i=10;
int j=0;
int main()
{
j=i;//This should be the first statement in the main() and you achieve the same functionality as ur code
return 0;
}
The only true C way is to initialize it at runtime. Although in C++ your code will work fine, without any compilation errors.
The C standard clearly prohibits initialization of global objects with non-constant values. The Section 6.7.8 of the C99 standard says:
All the expressions in an initializer for an object that has static
storage duration shall be constant expressions or string literals.
The definition of an object with static storage duration is in section 6.2.4:
An object whose identifier is declared with external or internal
linkage, or with the storage-class specifier static has static storage
duration. Its lifetime is the entire execution of the program and its
stored value is initialized only once, prior to program startup.

The idea behind this requirement is to have all static storage duration object initialized at compile time. The compiler prepares all static data in pre-initialized form so that it requires no additional initializing code at run time. I.e. when the compiled program is loaded, all such variables begin their lives in already initialized state.
In the first standardized version of C language (C89/90) this requirement also applied to aggregate initializers, even when they were used with local variables.
void foo(void)
{
int a = 5;
struct S { int x, y; } s = { a, a }; /* ERROR: initializer not constant */
}
Apparently the reason for that restriction was that the aggregate initializers were supposed to be built in advance in the pre-initialized data segment, just like global variables.

Use this:-
int i=10,j=1;
int main()
{
printf("%d",j);
}
Though it is a minor change but it will work

Related

Initialize static variable with the argument of a function

How can I do something like this?
void function(int n)
{
static int number = n;
.
.
.
}
If you want to initialize the static variable to n during the first invocation of the function, you can do it like this:
void function(int n)
{
static int initialized = 0;
static int number;
if (!initialized) {
number = n;
initialized = 1;
}
.
.
.
}
You can't initialize number to n directly since number is initialized at compile time, while n is known only at run time.
You cannot.
Quoting the C11 standard, chapter §6.7.9/P4
All the expressions in an initializer for an object that has static or thread storage duration
shall be constant expressions or string literals.
To elaborate, the objects with static storage duration are initialized only once, prior to the execution to the program. Thereby, it is not possible to use a run-time value to be used as the explicit initializer.
Related, from chapter §6.2.4
An object whose identifier is declared [...] with the storage-class
specifier static, has static storage duration. Its lifetime is the entire execution of the
program and its stored value is initialized only once, prior to program startup.

Why Global variable redefinition is not allowed?

#include<stdio.h>
int i =0;
i=2;
int main(){
// some Code here
return 0;
}
Error : /Users/vaibhavkumar/Documents/C/primeFactors.c|4|error: redefinition of 'i'|
Why redefinition of the variable is not allowed in C.
Global variables are stored in Data Segment(area of memory), at the same place where static variables are stored. How came static variables can be redeclared ?
That is not redefinition it is assignment.
Assignment is not the same as initialisation in C, and cannot be done outside a function - there is no thread of execution in that context, so when would it be done?
Variables with static linkage are no different to global variables (with extern linkage) in this respect, however static linkage variables are local to a single compilation unit and are not visible externally. If you declare two statics of the same name in separate compilation units, they are entirely independent and unrelated variables - they needn't even be the same type.
Note that static linkage is distinct from static storage, but they use the same keyword. All global and static linkage variables have static storage class implicitly, but a function local variable declared static has static storage class - i.e. it always exists - like a global, but is only visible locally.
Clifford explained the difference between assignment and initialization. But just fore completeness: You're not allowed to do assignments outside functions. Only initializations.
But why do you get this strange error? It's because of implicit declaration.
If we're talking about global space, then this
int i = 0;
i = 2;
is actually equivalent to this:
int i = 0;
int i = 2;
And this code will print 42:
#include <stdio.h>
i = 42;
int main(void) {
printf("%d\n", i);
}
The reason is backwards compatibility. Don't use this "feature"
The logic behind the strange message that seem very unrelated, is kind of like this:
Implicit declarations are allowed
Assignments are not allowed in global space
Therefore, i=2; in global space, must be a declaration

Static array initialization in C

I am reading the book Let us C by Yashavant Kanetkar.
In the Array of Pointers section there is a section of code which is giving me problems:
int main()
{
static int a[]={0,1,2,3,4}; //-----------(MY PROBLEM)
int *p[]={a,a+1,a+2,a+3,a+4};
printf("%u %u %d\n",p,*p,*(*p));
return 0;
}
What I don't understand is why has the array a have to be initialized as static. I tried initializing it without the static keyword but I got an error saying "illegal". Please help.
C90 (6.5.7) had
All the expressions in an initializer for an object that has static storage duration or in an initializer list for an object that has aggregate or union type shall be constant expressions.
And you are initializing an object that has an aggregate type, so the value must be known at compile time and the address of automatic variables are not in that case.
Note this has changed in C99 (6.7.8/4)
All the expressions in an initializer for an object that has static storage duration shall be constant expressions or string literals.
The constraint on object with aggregate or union type has been removed and I've not found it placed somewhere else. Your code with static removed should be accepted by a C99 compiler (it is by gcc -std=c99 for instance, which seems to confirm that I've not overlooked a constraint elsewhere).
My guess would be that the contents of an array initialiser have to be a compile-time constant. By using static on a local variable in a function you essentially make that variable global, except with a local scope.

Why I can not initialize and int value to a static variable

I am getting ERROR when I am running this program at the line
static int b = a; //error : initializer element is not constant
Can not understand why?
#include <stdio.h>
// #include <setjmp.h>
int main()
{
int a = 5;
static int b = a;
return 0;
}
Apart from the other reasons stated in other answers here, please see the below statement in the Standard.
The C Standard says this in Point-4 (Section 6.7.8 Initialization):
All the expressions in an initializer for an object that has static storage duration
shall be constant expressions or string literals.
Additionally, as to what is a constant expression, it says in Section 6.6 Constant Expressions as below:
A constant expression can be evaluated during translation rather than runtime, and
accordingly may be used in any place that a constant may be.
In C (unlike C++), the initializer for any object with static storage duration - including function statics - must be constant expressions. In your example a is not a constant expression so the initialization is not valid.
C99 6.7.8 / 4:
All the expressions in an initializer for an object that has static storage duration shall be constant expressions or string literals.
Static variable is always global in the sense it is not on any thread's stack, and it is not important if its declaration is inside a function or not.
So the initialization of the global variable b is performed during program start-up, before any function (including main) gets called, i.e. no a exists at that time, because a is local variable which gets its memory place on stack after the function (here main) is called.
Hence you really cannot expect the compiler to accept it.
Following from Als's answer ...
// This is really crappy code but demonstrates the problem another way ....
#include <stdio.h>
int main(int argc, char *argv[])
{
static int b = argc ; // how can the compiler know
// what to assign at compile time?
return 0;
}

Why can't I initialize a static variable with a non literal value?

I had this code:
int foo(void){
return 1;
}
int main(void){
static const int x = foo();
//do stuff
return 0;
}
But I got an error about initializing a static variable with a non-const value. I thought it had something to do with the const specifier, but it didn't. I ended dropping the const keyword and doing this:
int foo(void){
return 1;
}
int main(void){
static int x = 0;
if (x == 0) x = foo();
//do stuff
return 0;
}
Now, why can't the compiler just delay the initialization of the static int x variable until it's used, and more importantly, why can't it just put it in a read-write section, and just enforce that it's not written to in compile time? I'd like to use the const AND static keyword for improved semantics in my code, but I don't really care how the compiler handles this, just let it work.
Is my understanding of the C standard wrong? Or is my compiler sucking? It's MSVC 9.0.
C requires it.
From the C Standard:
(C99, 6.7.8p4) "All the expressions in an initializer for an object that has static storage duration shall be constant expressions or string literals."
Note that the const qualifier does not mean constant but rather read-only. A const object is not a constant in C.
The reason a static object cannot be initialized by a non constant value is related to the fact that the initialization of a static object is done "prior to program startup" (C99, 6.2.4p3).
The value for initialization must be determined at compile or link time. C doesn't have the concept of constructors that could be run at the startup of the program.
This constraint comes from C standard's section 6.7.8/4, so it's not just your compiler:
All the expressions in an initializer for an object that has static storage duration shall be constant expressions or string literals.
The reason for this is that unlike C++ standard, C sdoes not require execution environments to provide an entry point for pre-run initialization (while certainly not prohibiting it; The manner and timing of static initialization (5.1.2) is unspecified).

Resources