Is const really const?

  • Thread starter Rohit kumar Chandel
  • Start date
C

CBFalconer

Rohit said:
I have a doubt in const keyword. My understanding says that a
variable declared const can not be modified by the module it is
defined in. Then consider the following code segment:

main() {
const int p =5;
int* pp = &p;
++(*pp);
printf("%d\n",p);
}
To my surprise it increments value of p by one where p has
to be a constant. Please clarify my doubt.

If you turn up the warning level sufficiently the statement
int *pp = &p;
should trigger a complaint.
 
C

CBFalconer

Rohit said:
.... snip ...
I have one more question on const keyword. I have gone through lot
of reading material to find its answer, but in vain. Most of these
materials say that a variable declared to be const can not be
modified in the module in which it is defined. From this I assume
it can be modified by code outside the module it is defined in.
....

Don't assume. It simply should not be modified. That means it has
to be initialized in the definition statement, which in turn may be
a function call.
 
C

CBFalconer

Rohit said:
.... snip ...

Here is the cause of my confusion. Thought it'll help you to
understand the problem better. This is from one of training slides.
Goes like this:
/* real-time clock (hardware) */
const volatile T_RTC *pRTC = CLOCK_ADRESS;
...
void printTime()
{
printf("%d:%d:%d\n",
pRTC->std,pRTC->min,pRTC->sec);
}
...
void killRTC()
{
pRTC = NULL; /* <- ? */
}
...
??? Is the line in 'killRTC' allowed ???

Please indent your code, or possibly avoid using tabs.

The pRTC definition statement makes pRTC a pointer (non const) to a
(const) thing of type CLOCK_ADDRESS. You can modify the pointer
without modifying the thing pointed at.
 
R

Ravishankar S

Rohit kumar Chandel said:
Hi all,

I have a doubt in const keyword. My understanding says that a variable
declared const can not be modified by the module it is defined in. Then
consider the following code segment:
main()
{
const int p =5;
int* pp = &p;
++(*pp);
printf("%d\n",p);
}
To my surprise it increments value of p by one where p has to be a
constant. Please clarify my doubt.
you may be using a compiler which is fully ANSI compliant. I get this
warning when I try to compile the same code:

C:\>gcc const1.c
const1.c: In function `main':
const1.c:4: warning: initialization discards qualifiers from pointer target
type.

This warning may as well be an error be setting some other options. Or in in
other compilers its may be error by default.

Is const really const ? Just run the program with the change of making p
into a global variable and you get this result:

C:\>a.exe
13 [main] a 3232 handle_exceptions: Exception: STATUS_ACCESS_VIOLATION
10820 [main] a 3232 open_stackdumpfile: Dumping stack trace to
a.exe.stackdump

Now you can decide for yourself !

Regards,
Ravishankar
 
R

Ravishankar S

Thanks Mr Thompson for providing insight and at the same time correcting
english grammer as well :)
I have one more question on const keyword. I have gone through lot of
reading material to find its answer, but in vain. Most of these materials
say that a variable declared to be const can not be modified in the module
in which it is defined. From this I assume it can be modified by code
outside the module it is defined in. But what is a module here. Is it the
function, file or anything else.Does it mean that there is a normal way to
do it (apart from supressing warnings by using explicit cast). Please
clarify it with example.

A module means in C standard terms a "translation unit" -> the result of
running the preprocessor over a C source file...
 
R

Ravishankar S

Here is the cause of my confusion. Thought it'll help you to understand the
problem better. This is from one of training slides. Goes like this:
/* real-time clock (hardware) */
const volatile T_RTC *pRTC = CLOCK_ADRESS;
...
void printTime()
{
printf("%d:%d:%d\n",
pRTC->std,pRTC->min,pRTC->sec);
}
...
void killRTC()
{
pRTC = NULL; /* <- ? */
}
...
??? Is the line in 'killRTC' allowed ???

Explaination:
const volatile T_RTC *pRTC = CLOCK_ADRESS;
The keyword 'const' indicates that the variable must not be changed
by this module (but maybe changed by another module).
Here next variable to the right is '*pRTC',
so '*pRTC' will not be changed by this module,
so the value of the memory where 'pRTC' points to will not be changed.
But the variable 'pRTC' is allowed to change!
So the code on the page before is correct and works.

Explanation:

First understand that const means "read-only" (Read Dan Sak's article on
const : "Using "const" correctly !")

The global variable pRTC is pointer to an object that can only be read
through pRTC. pRTC by itself is normal pointer variable
which can be modified. Additionally the volatile says that the value of that
object can also change unpredictable, so no memory optimizations
may be performed by the compiler when **accessing that object through**
pRTC.

About pointer's and the type qualifiers (const and volatile)

const int i; // i is const
const int *cip; // cip points to a const int. cip is not const.
int *const cpi; // cpi is constant pointer (always points to the same
object). The object pointed to may be modified.


volatile int i; // i is volatile
volatile int *vip; // cip points to a volatile int. cip is not volatile
int *volatile vpi; // cpi is volatile pointer (can change unpredictably).
The object pointed to is a normal variable.
 
R

Ravishankar S

*pNum = 13; // this is perfectly correct.

Its correct only if you accept the outcome is undefined :)
// num isn't 12 anymore

printf("%d", num);

}

#define SIZE 10;

means SIZE is 10 in everywhere.

There is big difference between const variables and preprocesor
"constants"..
 
R

Rohit kumar Chandel

Ravishankar S said:
Rohit kumar Chandel said:
Hi all,

I have a doubt in const keyword. My understanding says that a variable
declared const can not be modified by the module it is defined in. Then
consider the following code segment:
main()
{
const int p =5;
int* pp = &p;
++(*pp);
printf("%d\n",p);
}
To my surprise it increments value of p by one where p has to be a
constant. Please clarify my doubt.
you may be using a compiler which is fully ANSI compliant. I get this
warning when I try to compile the same code:

C:\>gcc const1.c
const1.c: In function `main':
const1.c:4: warning: initialization discards qualifiers from pointer target
type.

This warning may as well be an error be setting some other options. Or in in
other compilers its may be error by default.

Is const really const ? Just run the program with the change of making p
into a global variable and you get this result:

C:\>a.exe
13 [main] a 3232 handle_exceptions: Exception: STATUS_ACCESS_VIOLATION
10820 [main] a 3232 open_stackdumpfile: Dumping stack trace to
a.exe.stackdump

Now you can decide for yourself !

Regards,
Ravishankar

I too got the warning :
c:\msvc\bin\rkc2.c(7) : warning C4090: 'initializing' : different const or
volatile qualifiers
But even after making p global, i get the same warning.
But my misconception is gone now....
I would put the summary in these words :

const is a promise made by the programmer to the compiler that once
initialized he'll not
change the value of a const variable. Compiler tries its best to keep the
promise ,by not allowing programmer modify the const variable directly (p++
gives an error, straightaway).

Modifying const variable by indirect means (as done by me by defining a
pointer to it)
results in undefined behaviour and may vary from compiler to compiler . So
some compilers may give warnings and others may give error for it.

Thanks to All
 
J

James Kuyper

Rohit kumar Chandel wrote:
....
I would put the summary in these words :

const is a promise made by the programmer to the compiler that once
initialized he'll not
change the value of a const variable. Compiler tries its best to keep the
promise ,by not allowing programmer modify the const variable directly (p++
gives an error, straightaway).

Modifying const variable by indirect means (as done by me by defining a
pointer to it)
results in undefined behaviour and may vary from compiler to compiler . So
some compilers may give warnings and others may give error for it.

I think your summary falls a little short, in that it misses a key
distinction. The easiest way to explain this is with code examples:


const int i=1;
int j = 2;

*&i = 3; // constraint violation
*(int*)&i = 4; // undefined behavior
*&j = 5; // defined behavior
*(const int *)&j = 6; // constraint violation

Do you understand why?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,780
Messages
2,569,611
Members
45,276
Latest member
Sawatmakal

Latest Threads

Top