If I convert const int to int inside a void it works.
But when I create an extern const int it doesn't.
void ReadFromEpprom()
{
int Start = 343;
const int End=Start; //This works
}
Example 2
Header File
extern const int End;
Source file
const int End;
void ReadFromEpprom()
{
int Start = 343;
End=Start; //This doesn't work
}
In second situation I get error:
(364) attempt to modify object qualified const
How can I solve this?
Should I make it with another way?
When you declare a constant variable this means the variable will not change.So it makes sense that constant variables must be initialized immediately.You are doing this in your first example which is correct.In your second example you have a constant variable and then you are trying to modify it's value.This is incorrect since the variable is already constant.
The extern here is a red herring.
If you use const int End then you need to initialise End at the point of this declaration. That's because it's const.
So const int End = Start; works fine, but const int End; is not syntactically viable.
In C you can't arrange things so you have a const at global scope and a function that sets the value at run-time. But what you could do is embed the value in a function (as as static), and call that function to initialise and subsequently retrieve the value.
Initialiazation versus assignment:
A const object can be initialized (given a value at the declaration), but not assigned (given a value later).
This is initialization, and "works". It is initialization the local variable End that exist inside ReadFromEpprom().
void ReadFromEpprom()
{
...
const int End=Start; //This works
End=Start; attempts to assigned End that exist at file scope, outside of ReadFromEpprom(). const objects cannot be assigned.
const int End;
void ReadFromEpprom()
{
...
End=Start; //This doesn't work
}
How can I solve this?
Let external code to read localEnd via a function ReadEnd(), yet allow local code to write localEnd.
static int localEnd;
int ReadEnd() {
return localEnd;
}
void ReadFromEpprom() {
int Start = 343;
localEnd = Start;
}
I agree with all the other answers.
It seems that you want to initialize a const value with a value that will be determined at run time, which is impossible.
What you can do is two workarounds.
Remove const. Add a comment near its definition that the variable is set only once in the very beginning.
Use a function instead of a const int variable; implement the "run code only once" idea inside this function.
Header file:
int CalcEnd();
Source file:
int CalcEnd()
{
static int init_done = 0;
static int result;
if (!init_done)
{
result = 343; // or any complex calculation you need to do
init_done = 1;
}
return result;
}
Note how the function uses static variables and logic to do initialization only once.
If you use the function idea, and don't want to remember typing the parentheses in the function call (CalcEnd()), you can define a macro:
#define End MyCalcEnd()
This will make it appear as if End were const int variable, when actually it's a function call. This usage of macros is controversial, use it only if you are sure it will not lead to confusion later.
Related
I am writing a code in C. It is in an environment with precoded functions, so I can't explain it completely. I wanted to iterate over a variable but this wasn't working. I eventually figured out this was because the variable was not defined globally but in a function, and was being redefined every time the function was called.
Now, at the top of my code, globally, I want to write the following code.
int killing_time = 20000;
int killing_period;
killing_period = killing_time;
The compiler gives me the following errors:
data definition has no type or storage class
Don't I clearly define it to be an integer?
initializer element is not constant
If I define killing_time as const int killing_time = 20000 it still gives the same error:
type defaults to ‘int’ in declaration of ‘killing_period'
I could of course define killing_period to be 20000 and just start iterating over that, but I want to know what is going on.
I hope we can figure this out together.
killing_period = killing_time; is not a valid statement in the global scope.
You can use assignment on declaration, but assigned variable (initializer element) must be constant:
const int killing_time = 20000;
int killing_period = killing_time;
Anyway, you shouldn't do it like that.
There's more than one way to do this, one of them is to pass the address of your iterator to the function where you use it, that way the changes made in the scope of the function are permanent:
void f1(int* i){
(*i)++; //will increment i
}
void f2(int* i){
(*i)++; //will increment i
}
int main ()
{
int i = 0;
f1(&i); //pass the address of i
f2(&i); //pass the address of i
printf("%d", i); // i = 2
return 0;
}
killing_period = killing_time; is executable code and you simply can't have executable code outside functions.
Nor can you do this:
int killing_time = 20000;
int killing_period = killing_time; // wrong
Because these are file scope variables and therefore have static storage duration. And variables with static storage duration can only be initialized by what C calls a constant expression. 20000 above is an integer constant expression, but killing_time isn't.
The simple fix is to do something like this instead:
#define KILLING_TIME 20000
...
int killing_time = KILLING_TIME;
int killing_period = KILLING_TIME;
killing_period = killing_time; is your problem. It is an executable statement and not allowed in global space... it must be within a function.
Still not sure what you are after, but would the following help?
int killing_time = 20000;
int killing_period = -1; // negative if not yet set
int your_function(void)
{
if ( killing_period < 0 ) {
/* one-time initialization on the first call */
killing_period = killing_time;
}
return killing_period;
}
If you need multiple functions setting killing_period it may be be best to burry that in a separate function dedicated to the test and set, or perhaps a macro.
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;
I have the following code below in a function.
char * stringFiveds = strtok(stringFive[3], "ds");
When I compile i get the warning unused variable.
I don't plan on using srtingFiveds in this function. I want to use it in main(). I have two parts to this question.
How to solve this warning if I don't want to use the stringFiveds in this function.
How do I make it accessible in other functions so i can use it in other function i will create.
I'm new to this, can you please be as detailed as possible.
If you don't want to use stringFiveds in the function, you can delete that variable declaration because you don't need it.
If you want to make it accessible to other functions, you can declare it as a global variable, or pass it as an argument to your other functions.
So instead of
char * stringFiveds = strtok(stringFive[3], "ds");
you can have just
strtok(stringFive[3], "ds");
If you want to declare stringFiveds as a global variable, just declare it outside of a function:
#include <stdio.h>
char * stringFiveds; // declare outside of function
void foo() {
// you can access stringFiveds here
}
int main() {
// you can also access stringFiveds here
}
If you want to pass stringFiveds as a function argument:
#include <stdio.h>
// declare outside of function
void foo(char * stringFiveds) {
}
int main() {
char * stringFiveds;
foo(stringFiveds);
}
If you do not plan to use a variable in a function, do not make a variable. If you make a variable simply for the side effects of calling a function, you could drop the assignment: C lets you call a function that returns a value as if it were a "procedure" - i.e. a void function.
Another alternative is declaring the variable in the global scope. If you choose this route, consider making the variable static to keep it within the scope of its translation unit. You could also make the variable global, but that is usually not a good option, because it exposes your data beyond the bounds where it is useful.
If you plan to pass it to another function, that would count as "using the variable", resolving the "unused variable" warning.
Note: in case you are curious on how to silence this warning anyway, a common trick is to cast your variable to void.
Well, you could do the gross thing and make it a global variable (i.e. declare is outside of your function).
But that really isn't a great solution. That breaks data encapsulation by giving everything in your .c file access to that variable, whether they need to know about it or not.
A better solution would be to pass in to your functions as a parameter where you need it.
For example:
function foo(char* stringFiveDs) { // use stringFiveDs here }
Or, you could pass in stringFive and declare stringFiveDs in the functions that you need it. So something like:
function bar(const char* stringFive) {
char* stringFiveDs = strtok(stringFive[3], "ds");
...
}
sample code
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char **func(const char *str, const char *delim){
char *strwk = strdup(str);
char **strs = malloc(sizeof(char*));
int count = 0;
char *p;
for(p=strtok(strwk, delim); p != NULL ; p=strtok(NULL, delim)){
strs[count++] = strdup(p);//cutting string copy into
strs = realloc(strs, (count+1)*sizeof(char*));//+1 : Also, reserved for NULL
}
strs[count] = NULL;//end mark
free(strwk);
return strs;
}
void func_d(char **ss){
char **sp = ss;
while(*sp)
free(*sp++);
free(ss);
}
int main(void){
char *stringFive[5] = {
"", "16X16", "1,2,3", "123d45s678", "last,,end"
};
char **stringFiveds = func(stringFive[3], "ds");
int i;
for(i=0; stringFiveds[i] != NULL; ++i)
printf("%s\n", stringFiveds[i]);
func_d(stringFiveds);
return 0;
}
I have a variable that I want to initialize at runtime before the rest of the program runs. After initialization, I don't want the value of the variable to change. Is there any C language construct to go about doing this ?
Let my main C program is contained in a file Prog.c
//Contents of Prog.c
//...includes.. and variable initialization
int main(..)
{
//Initialize variables here
//.. Huge program after this where I don't want these constants to change
}
You can do it indirectly through const pointers, at least:
typedef struct {
int answer;
} state;
const state * state_init(void)
{
static state st;
st.answer = 42; /* Pretend this has to be done at run-time. */
return &st;
}
int main(void)
{
const state *st = state_init();
printf("the answer is %d, and it's constant\n"," st->answer);
}
This way, all main() has is a const pointer to some state which it cannot modify.
A constant global should work, yes?
const int val = 3; // Set before main starts
// const, so it will never change.
int main(void)
{
printf("%d\n", val); // using val in code
}
However, if the value isn't known at compile-time, you can set it at run-time this way:
const int const* g_pVal;
int main(void)
{
static const int val = initialize_value();
g_pVal = &val;
printf("%d\n", *g_pVal);
}
The only way I can think of is if you read your value as a non constant and then call a function which take a constant value and pass your variable to it. Inside the function you make all the wished operations.
C - how to protect a variable from being accidentally changed after a certain point:
For example, in a C program, I declared an integer and changed it's value several times in the first part of the program. But then after a certain point I want to keep its value from being accidentally changed, or at least get a warning when any attempt to change its value happens. How do I do that?
You can't.
A possible solution would be to move the part of the function that modifies the variable into a separate function. That function would return the value of the variable which can be used to initialize a const variable:
int determine_value_of_a()
{
int result = 0;
/* Modifications of result. */
return result;
}
void f()
{
const int a = determine_value_of_a();
}
If using preprocessor macros is acceptable, then you can do this:
{ // Function body starts here.
int x = …;
… // Change x as desired here.
const int y = x;
#define x y;
… // “x” is actually the const y here.
#undef x
}
Generally, though, I would not recommend it. If you cannot trust the body of a single function to do things correctly, then the function is too complicated and ought to be restructured, as by calling another function to provide the value of the object.
Put the variable in a opaque struct with an indication of whether it can be changed.
Access the variable, both for getting and changing the value, from a function.
If the indication for changeability if off, the function does not allow changes
#include "swinger.h"
int main(void) {
struct moodswinger *var;
var = newswinger();
setvar(var, 42);
getvar(var);
swing(var, 0);
setvar(var, -1); /* oops */
}
The file swinger.h declares the functions.
The file swinger.c defines the struct and code.
int x;
x = …; // This is okay.
{
const int y = x; // Make a copy of x.
{
const int x = y; // Make a const copy of x that hides the original.
/* The compiler should produce a diagnostic if you
attempt to modify x here.
*/
}
}
Or, if you do not want the indenting to change:
int x;
x = …;
{ const int y = x; { const int x = y;
…; // x is const here.
} }
The only way you could do that would be
(a) to use a function to initialize the variable..
int main( int argc, char** argv )
{
const int myVar = initMyVar();
...
}
or (b) pass the variable into another function that does the other work...
void myWorkerFunc( const int myVar )
{
...
}
int main( int argc, char** argv )
{
int myVar = initMyVar();
...
myWorkerFunc( myVar );
}
Set a conditional breakpoint on it in your debugger. Then you will know if it ever changes. You could also write a "watchdog" type thread that scans your var every so often and warns on change, but that won't be immediate.
Neither of these are within the realm of C directly, but would help you determine if your var was erroneously changed.