c - Why are we allowed to change values of "const" qualified variables?Why pointers are allowed for this,but not assignment? -


consider following 2 programs prog1 , prog2.here if try change value of const qualified variable i using pointer ptr,i warning( not error) "initialization discards qualifiers pointer target type|",but program runs nevertheless , displays new value.but if try change value of i in second program using assignment statement,i error(not warning) assignment of read-only variable 'i'|.

here confusions arising premise:

1)why allowed change value of read-only const qualified variable in circumstance?doesn't defeat purpose of using const qualifier?shouldn't error if attempt so?

2)even if due strange reason allowed change values of constants,why discrimination between changing value of read-only const qualified variable using pointer (which allowed,with warning) , through using assignment operation (which not allowed , gives error)?

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

warning: initialization discards qualifiers pointer target type|

//prog2 #include <stdio.h>  int main() { const int i=8; i=10; printf("%d",i); } 

error: assignment of read-only variable 'i'|

edit h2co3

here change value of const qualified variable more once.i warning,the same in prog1

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

1) why allowed change value of read-only const qualified variable in circumstance? doesn't defeat purpose of using const qualifier?

trying change const-qualified object through assignment operator constraint violation:

6.5.16 under constraints:

2 assignment operator shall have modifiable lvalue left operand.

modifiable lvalues defined in 6.3.2.1 (1):

a modifiable lvalue lvalue not have array type, not have incomplete type, does not have const-qualified type, , if structure or union, not have member (including, recursively, member or element of contained aggregates or unions) const-qualified type.

as constraint violation, requires diagnostic message compiler per 5.1.1.3 (1):

a conforming implementation shall produce @ least 1 diagnostic message (identified in implementation-defined manner) if preprocessing translation unit or translation unit contains violation of syntax rule or constraint, if behavior explicitly specified undefined or implementation-defined. diagnostic messages need not produced in other circumstances.

but implementation not required reject invalid programmes, diagnostic message warning instead of error.

however, modifying object declared const through lvalue has not const-qualified type not constraint violation, although invokes undefined behaviour, 6.7.3 (6):

if attempt made modify object defined const-qualified type through use of lvalue non-const-qualified type, behavior undefined.

since it's not constraint violation nor invalid syntax, doesn't require diagnostic message emitted.

shouldn't error if attempt so?

you must diagnostic message if try modify object through lvalue const-qualified type.

since egregious violation of declared intentions, compilers emit error in these circumstances.

if try modify object const-qualified type through lvalue non-const-qualifed type in

const int i=8; int *ptr=&i; *ptr=9; 

the attempt modify i through expression *ptr = 9 invokes undefined behaviour, not constraint violation (or syntax error), hence not require diagnostic message (and none given).

there diagnostic message emitted initialisation

int *ptr = &i; 

because again constraint violation, per 6.5.16.1 (1):

one of following shall hold:

  • the left operand has atomic, qualified, or unqualified arithmetic type, , right has arithmetic type;
  • the left operand has atomic, qualified, or unqualified version of structure or union type compatible type of right;
  • the left operand has atomic, qualified, or unqualified pointer type, , (considering type left operand have after lvalue conversion) both operands pointers qualified or unqualified versions of compatible types, and type pointed left has qualifiers of type pointed right;
  • the left operand has atomic, qualified, or unqualified pointer type, , (considering type left operand have after lvalue conversion) 1 operand pointer object type, , other pointer qualified or unqualified version of void, , type pointed left has qualifiers of type pointed right;
  • the left operand atomic, qualified, or unqualified pointer, , right null pointer constant; or
  • the left operand has type atomic, qualified, or unqualified _bool, , right pointer.

that diagnostic warning , not error because 1 may explicitly cast const away,

int *ptr = (int*)&i; 

whereas 1 cannot cast away const i.

modifying object through pointer non-const-qualified object type has been obtained casting away const pointer const-qualified object type valid if object pointed modifiable. stupid example:

int = 8; const int *cptr = &i;  // valid, no problem adding const int *mptr = (int*)cptr; *mptr = 9;             // no problem, pointee non-const 

2) if due strange reason allowed change values of constants, why discrimination between changing value of read-only const qualified variable using pointer (which allowed,with warning) , through using assignment operation (which not allowed , gives error)?

directly assigning object const-qualified type not constraint violation, obvious violation of stated semantics. declaring object const explicitly says "i don't want object modified".

modifying object through pointer non-const-qualified type not constraint violation, , undefined behaviour if pointee has const-qualified type. converting pointer const-qualified type pointer corresponding non-const-qualified type allowed, , modifying pointee through pointer may valid, therefore warning, , if conversion not made explicit.

in given short example, compiler detect pointee has const-qualified type , therefore modification invokes undefined behaviour, in general such difficult, , impossible detect. therefore, compiler doesn't attempt detect simple cases, it's not worth effort.


Comments

Popular posts from this blog

jquery - How can I dynamically add a browser tab? -

node.js - Getting the socket id,user id pair of a logged in user(s) -

keyboard - C++ GetAsyncKeyState alternative -