What does const int * ptr = & i mean? Why does it accept non-constant addresses?

Your answers are trying very hard to eliminate this basic error in my understanding of const , which I understood today.

In my program, I used the operator const int *ptr=&i; but did not use any const qualifier for variable i . Two things confuse me:

1) When I try to change the value of i using ptr , where I used const int *ptr=&i; , I get an error assignment of read-only location '*ptr'| even though I did not declare the variable i with the const qualifier. What exactly means the statement const int *ptr=&i; and how it differs from int * const ptr=&i; ?

It was drilled into my head that const int *ptr=&i; means that the pointer stores the address of the constant, and int * const ptr=&i; means that the pointer itself is constant and cannot change. But today, one user told me in a discussion ( LINK ) that const int *ptr means the memory pointed to must be treated as nonmodifiable _through this pointer_ I find this something new, because this view means "some kind of pointer of choice cannot change the meaning (while others may). " I wasn’t aware of such selective declarations !! But the 180k veteran confirmed that this user is right! .. So, can you formulate this in a more clear, more detailed and rigorous way? What exactly does const int * ptr = & i; mean?

2) I was also told that we can lie to the program in the instruction const int *ptr=&i; by assigning a pointer to a volatile pointer. What does this mean that we are allowed to do this? Why don't we get a warning if we assign an inconsistent address to the ptr , which is expecting a constant address? And if he so forgives the assigned address of inconstant, why does he give an error when we try to change the value of this inconstant, which is a reasonable thing, and the pointed variable is inconstant?

 #include <stdio.h> int main () { int i=8; const int *ptr=&i; *ptr=9; printf("%d",*ptr); } 

error: assignment of read-only location '*ptr'|

+4
source share
2 answers

In the definition of const int *ptr = &i; essentially says: "I will not change i through ptr ." He does not say that int , which ptr points to const , he says that ptr should not be used to change it.

This conversion is allowed because it makes sense: since i not const , I can allow it to be changed, but I can also not change it. No rule is interrupted if I do not want to change i . And, if I create a pointer to i and say: “I will not use this pointer to change i ”, that’s good too.

The reason you want to do this is to pass the address of the object to a routine that takes a pointer to a const object. For example, consider the strlen procedure. The strlen routine does not change its input, so its parameter is a pointer to const char . Now I have a pointer to char , and I want to know its length. Therefore, I call strlen . Now I pass a pointer to char as an argument to the parameter, which is a pointer to const char . We want this transformation to work. This makes sense: I can change my char if I want, but the strlen routine is not suitable, so it treats them as const char .

1) You get an error message with *ptr = something; because you declared ptr as a pointer to const int , but then you broke your promise not to use ptr to change int . The fact that ptr points to an object that is not const does not cancel your promise not to use ptr to change it.

2) It is incorrect to assign the address of a const object to a pointer to const . The destination does not say that the object is const , it says that the pointer should not be used to modify the object.

Also, although you did not ask this, the const attribute in C is not completely required. If you define an object as const , you should not modify it. However, there are other situations in which a pointer to const is passed into a subroutine that converts it to a pointer to const . This is actually a defect in the language, the inability to save all the information necessary for processing const ways that we might prefer. An example is the strchr routine. Its declaration is char *strchr(const char *s, int c) . The s parameter is equal to const char * , because strchr does not change its input. However, the pointer that the strchr routines strchr is inferred from s (it points to one of the characters in the string). So, inside strchr converted a const char * to char * .

This allows you to write code that goes from char * to strchr , and uses the return pointer to change the string, which is good. But this means that the compiler cannot completely protect you from errors, such as passing const char * to strchr and using the return pointer to try to change the string, which may be an error. This is a flaw in C.

+6
source

Discard this:

const int * ptr means "* ptr is const int"; those. "ptr is a pointer to const int". You cannot write * ptr = 9 since * ptr is a constant. However, you can write int j; ptr = & j; since you can allow the ptr pointer to specify another int.

int * const ptr means "ptr is a constant pointer to int". You can write * ptr = 9, since you are not changing the address pointed to by ptr. You cannot assign it to anything else; those. int j; ptr = & j; will not compile.

As for the second part of (2), it is very useful to have const int * ptr, especially in function prototypes, since it tells the calling function that the variable pointed to by ptr will not be changed by the function. As for assignment, if you have int * m = & i, then ptr = m is ok, but m = ptr is not suitable, since the latter will “drop the constant”; those. you bypassed const.

-1
source

Source: https://habr.com/ru/post/1480706/


All Articles