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;
}
Related
As per 6.6.10
10 An implementation may accept other forms of constant expressions.
the implementation may consider const (or even not const as answers are focused on it - but it is not the core of the question) variables as constant expressions.
Is my logic correct? If not why?
Some examples:
//file scope
int a = 5;
const int b = 10;
int c[a];
int d[b];
IMO both meet the requirements. They can be evaluated compile time. The value is known and the static arrays have sizes known compile time.
volatile int x = 5; //cannot be considered as known compile time. ????
void foo(int a)
{
static int b[a];
}
In this example a cannot be evaluated compile time - so it cannot be used as constant expression
Constant expressions doesn't have anything to do with the const qualifier. See 6.6/6 for the definition of an integer constant expression.
6.6/10 refers to the earlier parts of the same chapter speaking of integer constant expressions, constant expressions in initializers and so on. I believe the quoted part refers to various corner case expressions such as this:
static int x;
static int y = (int)&x;
This isn't strictly conforming since &x is not regarded as a integer constant expression but as an address constant. Neither gcc nor clang accepts it. I believe 6.6/10 allows compilers to support code like the above example as an implementation-defined extension.
Building on the link from #ryyker 's comment.
In C, an expression is considered constant if it's made entirely out of compile-time constants (i.e. literals). const variables are not accepted because const doesn't necessarily mean "constant"; it just means that a variable is immutable (read-only) from the perspective of the current compilation unit.
Consider a function like this one...
int add(const int a, const int b) {
return a + b;
You could call this function by passing in compile-time constants, but you could also pass in mutable variables. If you pass in a variable, it is treated as const (read-only) for the purposes of that scope, but its value still isn't known at compile time so it isn't a "constant".
This question already has answers here:
Error "initializer element is not constant" when trying to initialize variable with const
(8 answers)
Closed 6 years ago.
What I thought static pointer is like other static variables, ones initialised with an value it have same value till end, like that the same address will be held in the static pointer. But in this case the compiler is throwing error
//initialiser element is not constant static int *a = &b[0];
#include <stdio.h>
int main(void)
{
int b[2];
static int *a = &b[0]; // removing static the program works well.
printf("%u",a);
a = &b[1];
printf("%u",a);
return 0;
}
So what is the use of static pointer?
In C, your code doesn't make sense. b has automatic storage duration so conceptually will have a different address each time main is encountered. The static will be initialised only once, and on subsequent invocations of main it may well point to something invalid.
But, and this is the interesting bit, in C++ it ought to make sense since you are not allowed to call main yourself: the behaviour on your doing so is undefined. So the inference of this is that the compiler ought to know that the static is valid for the lifetime of main, and compile the code! Perhaps there is something in the C++ Standard that explicitly forbids this.
In C you are allowed to call main recursively (even implicitly recursively), so the compiler ought to emit an error.
You have two options. Add static to int b[2], or remove it from int *a.
The address of b isn't static. It's variable, because b is a variable with automatic storage.
There may be confusion about static vs const.
Const variables will keep the same value from the time they are initialized until they go out of scope, unless const_cast<> is used, though as #Bathsheba mentioned in comment, use of const_cast<> on a variable declared const is undefined.
Static means it will get initialized at the spot first reaches but then not go out of scope until the end of program execution.
This question already has answers here:
Error "initializer element is not constant" when trying to initialize variable with const
(8 answers)
Closed 9 years ago.
Let me exemplify this,
int a = 100;
int b = a;
int main(int argc, char **argv, char ** env)
{
printf("The value of b=%d\r\n",b);
return 0;
}
Now, I get the compilation error as expected.
[joshis1#localhost global_var]$ gcc global_var.c -o global_var.out
global_var.c:4:1: error: initializer element is not constant
int b = a;
^
What I want to learn here is why do I get the error? why compiler restricts this operation.
I understand that initialized global variables are stored in Data segments. The compiler could have first resolved the value of a,and then could have assigned the same value to b. Why it lacks this feature? Is it complex for compiler to do? Is there any rationale behind this functionality or just a pitfall of C?
The official documentation, taken from line 1644, 6.7.8 Initialization, says:
All the expressions in an initializer for an object that has static storage duration shall be constant expressions or string literals.
Why the rule exists is a more difficult question - perhaps as you suggest it is difficult for the compiler to do. In C++ such an expression is valid, but global initialiser may invoke constructors, etc, whereas for C, to keep things compact, globals are evaluated at the compile phase. int b = a; is evaluable at compile time, but what about int b = a + c;? int b = pow(a, 2);? Where would you stop? C decides that not allowing you to start is the best solution.
From your comment:
...how can I force compiler to make this work?
Well you can't make the compiler accept what you have but you can accomplish your goal by defining the value you want to assign to both variables.
#define INITIAL_VALUE_FOR_A 100
int a = INITIAL_VALUE_FOR_A;
int b = INITIAL_VALUE_FOR_A;
Now if you need to change the initial value, you only need to change it in one place;
C is portable to very simple, small machines. Evaluating expressions that aren't constant requires runtime code, in a function. In embedded programming you might not want any functions (or code) that you did not explicitly program.
Your compiler probably will evaluate the initializer as a language extension, if configured with different options. If that fails, you could try C++ (even just the C-like subset) or another language that does more things you like :v) .
Others have stated why initializers in general can't be allowed to be arbitrary expressions.
The way to "force the compiler to accept the code" is to change the code. The canonical way to perform arbitrary initialization of file scope, external linkage (vulgo: "global") variables is to call an initialization function at the start of main() that does all the initialization in the sequence you need:
#include <stdio.h>
int a;
int b;
void init(void)
{
a = 100;
b = a;
}
int main(int argc, char **argv)
{
init();
printf("The value of b=%d\n", b);
return 0;
}
#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
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).