This question already has an answer here:
Confusion regarding modification of const variable using pointers
(1 answer)
Closed 6 years ago.
I have some code with const void* as below:
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
int main()
{
const int p = 10;
char s[] ="I am newbie";
const void *vp;
vp = &p;
*(int*)vp = 11;
printf("%i\n", *(int*)vp);
vp= s;
printf("%s\n", (char*)vp);
return 0;
}
My question is why const void* vp still be updated?
As my understanding, const variable can not be updated directly, is that correct for all types?
You effectively removed the const when you got a pointer to your int, cast the pointer to something without the const, and then changed the value of what that points to.
*(int*)vp = 11;
You can cast a pointer type to any other pointer type.
Modifying a const variable like this is undefined behavior. For example, the compiler might have seen that the variable was const, realized that it could pre-compute what the printf functions would print, and do the substitution at compile time as an optimization. The compiler would be allowed to do this because it thinks the variable is const.
Related
This question already has answers here:
Can a const variable be used to declare the size of an array in C?
(5 answers)
Closed 4 years ago.
I've found an interesting fact, and I didn't understand how is it works.
The following piece of code just works perfectly.
#include <stdio.h>
int main(){
const int size = 10;
int sampleArray[size];
typedef char String [size];
return 0;
}
Then, I tried to use only and only the constant variable with a global scope, and it's still fine.
#include <stdio.h>
const int size = 10;
int main(){
int sampleArray[size];
typedef char String [size];
return 0;
}
But, if I change the arrays's scope to global as well, I got the following:
error: variably modified ‘sampleArray’ at file scope
#include <stdio.h>
const int size = 10;
int sampleArray[size];
typedef char String [size];
int main(){
return 0;
}
And I didn't get it! If I'd replace the const variable for ex. to #define it'd be okay as well.
I know that the #define variable is preprocessed, and as far as I know the const variable is only read-only. But what does make the global scope after all?
I don't understand what is the problem with the third piece of code, if the second one is just okay.
Variable Length Arrays may have only automatic storage duration. VLAs were introduced in C99.
It is not allowed to declare a VLA with the static storage duration because the size of VLA is determinated at the run time (see below)
Before this Standard you can use either a macro like
#define SIZE 10
//...
int a[SIZE];
or a enumerator of an enumeration like
enum { SIZE = 10; }
//...
int a[SIZE];
By the way you may remove the const qualifier and just write
int size = 10;
instead of
const int size = 10;
(In C++ you have to use the const qualifier though in C++ there are no VLAs except that some compilers can have their own language extensions)
Take into account that the sizeof operator for VLAs is calculated at the run-time instead of the compile-time.
I was looking at an example which showed that why typedef'ng a pointer is a bad practice. The part I didn't understand about the example is that why the compiler wasn't able to catch the problem. I elaborated the example into the following code:
#include <stdio.h>
typedef int *TYPE;
void set_type(TYPE t) {
*t = 12;
}
void foo(const TYPE mytype) {
set_type(mytype); // Error expected, but in fact compiles
}
int main() {
TYPE a;
int b = 10;
a = &b;
printf("A is %d\n",*a);
foo(a);
printf("A is %d\n",*a);
return 0;
}
So, I was able to change the value of a. Even though, the example explained that you would have to do, typedef const int *TYPE, to solve the problem, I dont understand why the compiler was not able to catch the error when I am setting TYPE to be const in the function argument itself. I am sure I am missing something very basic.
The issue here is confusion about what const is being applied to: is it applied to the pointer value itself, or the value being pointed to?
const TYPE x is saying that the pointer value should be constant. This is roughly equivalent to int * const x. Note that the following code does result in an error:
int b = 10;
const TYPE p = NULL;
p = &b; // error here (assign to const)
What you were expecting is const int * x, which makes the value pointed to by x a constant.
Since the typedef hides the fact that TYPE is a pointer type, there's no way to specify that the thing pointed to by TYPE should be const, aside from declaring another typedef:
typedef const int * CONST_TYPE;
However, at this point the typedef seems to be causing more trouble than it solves... Probably not the best idea.
This question already has answers here:
Changing value of const int using using pointer [duplicate]
(2 answers)
Closed 8 years ago.
I got a program crash when I am trying to modify constant variable through a pointer.
#include <stdio.h>
static const int x = 5;
void changeX(int *x)
{
(*x) = 20;
printf("%d", (*x));
}
int main(void)
{
printf("Jelele");
changeX((int *)&x);
return 0;
}
I know it isn't a good practice and there is no need to make such that ... I am just testing something ...
My question is:
Why program crashes ?!
static const int x = 5;
This is a constant variable stored in read-only location so when you try to write to this location then you see a crash.
Like
(*x) = 20; /* This is UB */
Check the below link:
Where are constant variables stored in C?
You could change where the pointer x points to, but as the integer x is constant, its value cannot obviously be changed by definition.
#include<stdio.h>
#include<conio.h>
int main()
{
int const anila=10;
int *ptr=&anila;
clrscr();
printf("%d",*ptr);
getch();
return 0;
}
why the warning occurs in the program? what is suspicious pointer conversion here? and *ptr=&anila; *ptr will have the address of anila. how it prints 10 correctly?
anila is const, but ptr is a non-const pointer, think about this code:
*ptr = 42;
It's trying to modify *ptr, i.e, anila here, that's why there's a warning.
The reason you get that warning is so that the compiler can warn you that you do not accidentally modify the variable anila:
#include<stdio.h>
int main()
{
int const anila=10;
int *ptr=&anila;
*ptr = 100; // --> This should not be done since you declare anila as const
printf("%d",*ptr);
return 0;
}
The above code works fine when you as a programmer did not want something like this to happen (i.e. Modifying a variable marked as read-only). Do this and the code will not compile:
int const anila=10;
int const *ptr=&anila;
prog.c:6:6: error: assignment of read-only location ‘*ptr’
*ptr = 100;
Also please know that conio.h is non-standard.
You assign the address of const int to the pointer to int. The pointer should be to const int too - this should get rid of the warning.
This question already has an answer here:
C++ forbidden pointer to pointer conversion
(1 answer)
Closed 8 years ago.
Is there way to create an const int** from an int**?
I'm currently using:
const int **pixel2=*pixel;
const char **header2=*header;
I keep getting the error: cscd240HW34.c:52:21: warning: initialization from incompatible pointer type [enabled by default]
const int **pixel2=*pixel;
If pixel is already of type int ** then:
const int **pixel2 = (const int **)pixel;
By way of explanation: the reason a cast is required is because this still doesn't give you as much type-safety as you might think. For example you could now write:
const int c = 'x';
*pixel2 = &c; // fine, both are const int *
**pixel = 'y'; // no compiler error, but UB as we modify a non-writable object
So, see if there is another way to do what you want to do. Note that this definition of pixel2 avoids that exploit
const int * const * pixel2;
although sadly C still requires a cast to assign pixel to pixel2.
This question is 11.10 in the c.l.c. FAQ.