Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
#include<stdio.h>
void main() {
const int convalue=64;
int *point;
point = &convalue;
(*point)++;
printf("address of point is %p address of convalue is %p\n",point,&convalue);
printf("convalue is %d and point is %d\n",convalue,*point);
}
How can i modify the constant variable value
How can i modify the constant variable value
You cannot change the value of a constant1 after initialisation. That's what "constant" means.
You can change the program by removing the const qualifier. Then you can change the value. Or, you can conditionally choose another value during initialisation.
1 Except if the constant is of class type, then you can change mutable members of the object.
void main()
The pogram is ill-formed. main must return int in C++. It may not return void.
point = &convalue;
The pogram is ill-formed. A pointer to const doesn't implicitly convert to pointer to non-const. The type system of the language protects you from making mistakes such as this.
(*point)++;
The behaviour of the program is undefined. Const objects must not be modified. This is a bug. Don't write this in a program.
We can't and should never try to modify the value of a const variable. Also,
Any attempt to modify a const object results in undefined behavior.
Also,
note that undefined behavior means anything can happen including but not limited to program being successfully compiled and giving your expected output. But don't rely on the output of a program that has undefined behavior.
For more reading on undefined behavior you can refer to undefined behavior's documentation which mentions:
there are no restrictions on the behavior of the program.
Mistake 2
There is another mistake(in addition to undefined behavior) in your program(in C++). In particular, you should replace
int *point;//INCORRECT
with
const int *point;//CORRECT, note i have added const here
Mistake 3
You should replace void main() with
int main()
Because void main() is not standard C++ as Bjarne Stroustrup made this quite clear in this article
The definition void main() is not and never has been C++, nor has it even been C.
Simply – you can't. "Constant" is constant.
If you need to, you have to use variable instead.
Anyway, there is one possibility to get what you (maybe) want – preprocessor. Question is a bit strange, so I think you could be satisfied by that.
Using preprocessor you can determine what is the initial value of const. (And more, but that's not this case.) Still you can't modify it after it's initialized, but maybe it will be enough for you. For example:
#include<stdio.h>
void main() {
const int convalue=
#ifdef CLI_PROVIDED
CLI_PROVIDED;
#undef CLI_PROVIDED
#else
64;
#endif
int *point;
point = &convalue;
(*point)++;
printf("address of point is %p address of convalue is %p\n",point,&convalue);
printf("convalue is %d and point is %d\n",convalue,*point);
}
Normal compilation will initialize const with value 64. Compilation with option g++ -DCLI_PROVIDED=123 will modify initial value of const BEFORE compilation (this is just text operation) and then compile it with value 123.
Preprocessor is working with code before compilation.
If you want to (for example) create program for multiple operating systems, it will be useful.
Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
I can pass arguments to a function in C in the following manner without any warnings or errors using gcc on ubuntu-64bit:
void func(char* test){
// do something here
}
void main() {
func((char*) "smaps");
}
I did not find a lot of examples about passing anonymous parameters to functions in C apart from one comment on a similar question about C++. I am thinking of using this technique (a lot) in my code which would be compiled on multiple AMD64/ARM devices as they become available (with mostly debian-based OSes). My question is, is this compiler-specific?
Output of gcc --version:
$ gcc --version
gcc (Ubuntu 6.3.0-12ubuntu2) 6.3.0 20170406
UPDATE: Even though I think 4386427's was good enough for me, I would explain a bit more about the question as it was put on hold. I have a script which makes several calls to a specific function which takes in a char** as argument. I was of the view that I would need to explicitly declare a char** separately and pass it to the function by name every time I made a call to the function. I thought it would be more convenient to declare a string and pass it to the function at the same time; something like:
func( (char**) {"first_string", "second_string"} ).
My initial concern was is this allowed in C generally or is this a compiler-specific feature? 4386427's answer suggests that it is not compiler-specific, however I should be careful that the char** passed to the function would be immutable.
All parameters in C are passed by value. No information about the original object from which the value came is passed to the called function. In this sense, all C arguments are anonymous; no information about the identifier used in the calling function is passed.
In func((char*) "smaps");, the string literal "smaps" is converted to a pointer to char. Only the value of the pointer is passed to func. This is standard C.
(If you do want to pass information about an object to a function, you must do that manually. For example, you can take the address of an object and pass the resulting pointer to the function. Or you can pass the number of elements in an array to a function, along with the address of the first element.)
(In C, string literals such as "smaps" are automatically converted to a pointer to their first character, so you do not need to manually convert them with a char * cast. [This automatic conversion does not occur when the string literal is the operand of sizeof, _Alignof, or & or when it is used to initialize an array.])
It depends on what you are doing in the function. As long as you don't try to modify what test is pointing to, there is no problem. To indicate that it can't be changed, it is good to add const.
Like this the code is fine:
#include <stdio.h>
void func(const char* test){
printf("%s\n", test);
}
int main(void) {
func("smaps1");
func("smaps2");
func("smaps3");
func("smaps4");
return 0;
}
But if you try to change the value like:
void func(char* test){
test[0] = 'A';
printf("%s\n", test);
}
you have undefined behavior because modifying a string literal is undefined behavior.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
Is the following code in C correct? I am not 100% sure about the scope of function parameter "a":
void method(int a)
{
MyStruct mystruct;
mystruct.value = (void*) (&a);
nested_method_call(mystruct);
}
Let's assume it's:
void method(int a)
{
MyStruct x;
struct.value = (void*) a;
nested_method_call(x);
}
since struct cannot be used as a variable name.
a's scope is the function, so it is alive during nested_method_call, however, that is absolutely irrelevant because your nested_method_call isn't referring to it -- it's using a copy of a reinterpreted as void*. (Such reintepretation makes the code quite unportable and unusual, by the way. It might be a mistake.)
Edit:
void method(int a)
{
MyStruct mystruct;
struct.value = (void*) &a;
nested_method_call(mystruct);
}
is valid (though it's usually a good idea to pass structs by pointer because it's faster for any but very small structs). &a is a valid reference until the } of method.
You also shouldn't need that cast. If .value is void*, you don't need it. If it isn't, the cast makes &a convertible to any other data pointer, which is potentially a dangerous hole in the type system.
First of all, struct is a keyword in C and cannot be used as a variable name, so this is wrong code.
After that, casting an integer to pointer (and vice-versa) is implementation defined behaviour. You should better use uintptr_t for better, if you have to get that conversion done.
That said, from the basic premises of your question, the logic behind the code seems legit, there's no problem with the scope. In case you meant to ask about the lifetime ["The lifetime of an object is the portion of program execution during which storage is
guaranteed to be reserved for it"], then, it is until the end of the method() function and you're using it inside that limit, so you're good to go.
Corrected code: struct.value = (void*)&a;. Also some other validation needs to be done.
So, if you fully correct your code so that it complies properly then Correct word would be Lifetime instead of Scope. Lifetime of a will be till the end of function method. Therefore, a can still be accessed inside nested_method_call via pointer struct.value assuming type of struct.value is int*.
This question already has answers here:
Const correctness for value parameters
(6 answers)
Closed 6 years ago.
I do understand the meaning of const for pointers or structures that have to be passed by reference to a function. However in the example:
void foo(const int a);
the variable a is passed on the stack. There is no harm to the caller to modify the content of the stack so const looks pretty useless in this situation.
Furthermore, if I cannot modify a, I can still make a copy of a and change this copy:
void foo(const int a)
{
int b = a;
b++;
}
In which situation does the const keyword will be useful when applied to a scalar function argument (not a pointer)?
Code like void foo(const int a) is not really meaningful, nor is it "const correctness" as such.
Sometimes overly pedantic programmers get the weird idea that they need to declare common parameters as const just because a function doesn't modify the actual parameter. But most often, functions do not.
The point is, the variable is a copy of the original, so what your function does with it doesn't matter the slightest!
So this is not even a way of writing self-documenting code, because all it does is to tell the caller what's going on internally inside your function. The caller doesn't care and shouldn't care.
It's unnecessary to use const for a value parameter, but it has its value if what you want is to guarantee the code does what you intend.
Here there's an answer with some example of use cases
It's the same thing as declaring any constant variable
const int size = some_other_variable + 5;
It is a good programming practice to declare variables as const if you know their values will not change. That way from declaration you can avoid that someone accidentally changes their value further down the function.
It means that an implementer of the function cannot change the value of the input parameter a that the function receives by value.
It can lead to increased program stability.
(Personally I dislike the style as I find it too verbose).
If you do adopt this style, then note well that you only need to put the const in the parameter list of the function definition, you don't need it in the declaration.
It's useful mostly for purposes of self-documenting your code.
For future people looking through your source code, the const serves to emphasize your intent (that none of the code in foo() should attempt to modify a).
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question appears to be off-topic because it lacks sufficient information to diagnose the problem. Describe your problem in more detail or include a minimal example in the question itself.
Closed 8 years ago.
Improve this question
I define a function, let's say myfun in file2.c. myfun returns a float value. In file1.c I don't have any declaration for this function. I directly call myfun without any prior declaration and assign it's return type to an integer variable, let's call it retValInt. I compile them together. When I print retValInt, it gives me garbage. Why doesn't it cast the returned value and give the appropriate integer?
The following is the exact code:
//file1.c
#include<stdio.h>
int main()
{
int retValInt = myfun(123.456);
printf("The value returned is %d\n",retValInt);
return 0;
}
//------------------------
//file2.c
float myfun(float a)
{
return a;
}
I expected the output to be 123, but it is 446676599.
How could the compiler possibly know, when compiling main, that myfun returns a float that needs to be cast to an int?
You're asking why the compiler didn't make the code do something it could not possibly have known it needed to make the code do. So the answer is obvious -- the compiler had no way to know that's what you wanted. In fact, it is reasonable for the compiler to assume that if you wanted it to do that, you would have told it to. So one can argue that the behavior you seem to expect would actually be incorrect and quite baffling. (You never told the compiler to do that, so doing it would be bad.)
In C, specifically in C89 (but not in C99 or C11!), functions that have not been declared are implicitly assumed to have return type int. If your actual function does not have that return type, your program is ill-formed (it has undefined behaviour), and no diagnostic is required.
Your code is not valid C99, but compiler support for C99 is half-hearted at best.
To write a prototype before using the function.
float myfun(float);
int main()
This question already has answers here:
Can we change the value of an object defined with const through pointers?
(11 answers)
Closed 5 years ago.
I am able to change the value of const modified variable in gcc but not in other compilers.
I have tried this code on gcc, which updates the value of i and j (11). With an online compiler, I get different values.
#include<stdio.h>
void main() {
const int i=10;
int *j;
j = &i;
(*j)++;
printf("address of j is %p address of i is %p\n",j,&i);
printf("i is %d and j is %d\n",i,*j);
}
Yes, you can do it with a little hack.
#include <stdio.h>
int main(){
const int a = 0;
*(int *)&a = 39;
printf("%d", a);
}
In the above code, a is a const int. With the little hack, you can change the constant value.
Update: Explanation
In the above code, a is defined as a const. For example a has a memory addr 0x01 and therefore &a returns the same. When it is casted with (int *) it becomes another variable referred as a pointer to the const. When it is accessed with * again, the another variable can be accessed without violation of the const policy because it is not the original variable, but the changes are reflected because it is referred as address to the pointer.
This will work on older versions like Borland C++ or Turbo C++, however no one is using it now a days.
It's "undefined behaviour", meaning that based on the standard you can't predict what will happen when you try this. It may do different things depending on the particular machine, compiler, and state of the program.
In this case, what will most often happen is that the answer will be "yes". A variable, const or not, is just a location in memory, and you can break the rules of const and simply overwrite it. (Of course this will cause a severe bug if some other part of the program is depending on its const data being constant!)
However in some cases -- most typically for const static data -- the compiler may put such variables in a read-only region of memory. MSVC, for example, usually puts const static ints in .text segment of the executable, which means that the operating system will throw a protection fault if you try to write to it, and the program will crash.
In some other combination of compiler and machine, something entirely different may happen. The one thing you can predict for sure is that this pattern will annoy whoever has to read your code.
Try this and let me know.
How to modify value of const variable?
No! You shouldn't modify a const variable.
The whole point of having a const variable is to be not able to modify it. If you want a variable which you should be able to modify, simply don't add a const qualifier on it.
Any code which modify's a const forcibly through (pointer)hackery invokes Undefined Behavior.
An Undefined Behavior means that the code is non conforming to the standard specifications laid out by the C standard and hence not a valid code. Such a code can show any behavior and it is allowed to do so.
By defining i as const, you promised not to modify it. The compiler can rely on that promise and assume that it's not modified. When you print the value of i, the compiler can just print 10 rather than loading whatever value is currently stored in i.
Or it can choose to load the value. Or it can cause your program to crash when you try to modify i. The behavior is undefined.
You'll likely see different behavior with gcc depending on the optimization options (-O1, -O3).
Oh, and void main() is incorrect; it should be int main(void). If your textbook tells you to use void main(), you should get a better book.
Take a look at Can we change the value of an object defined with const through pointers?
Long story short, it's an undefined behaviour. It can result dependently on compiler/machine.
You can not modify the value of const variable if you compile this code in gcc it will show
error: invalid conversion from ‘const int*’ to ‘int*’ [-fpermissive]
and show undefined behave
The maiin thing is that we can only modify the variable when we can access the address without address we can't do anything. That's the same thing with Register storage class.