Re: Whats the deal with 'const'?
- From: Jack Klein <jackklein@xxxxxxxxxxx>
- Date: Sat, 15 Jul 2006 12:15:44 -0500
On 15 Jul 2006 09:34:40 -0700, "Snis Pilbor" <snispilbor@xxxxxxxxx>
wrote in comp.lang.c:
Whats the point of making functions which take arguments of a form like
"const char *x"? It appears that this has no effect on the function
actually working and doing its job, ie, if the function doesn't write
to x, then it doesnt seem like the compiler could care less whether I
specify the const part. Quite the opposite, if one uses const
liberally and then later goes back and changes the functions, headaches
will inevitably occur as one tries to compile and the compiler gripes
because now suddenly you ARE writing to x, so you have to go back and
remove the const keyword, and this might mean painstakingly removing it
from dozens of lines if the function in question is deeply nested
amidst a family of functions that call eachother and all have 'const'
keywords.
The definition of a function parameter as "const char *x" defines that
argument as a pointer to one or more constant characters. The pointer
may be changed, any characters that it points to may not. This means
it may be called with a pointer to constant or non constant
characters. It is also a promise by the implementer of the function
that it will not attempt to modify any character(s) pointed to by 'x'.
Given a prototype of a function that accepts a pointer to const char,
a programmer may call that function with a pointer to one or more
chars that may not be modified, either an actual constant char or
array of constant chars, or a string literal.
Or it may be that the data pointed to is not a literal or constant,
but the caller needs it to keep its present value for further
processing.
Is const, in this context (ie passing const arguments to functions)....
1. A Java-like "babysitter" keyword based on the premise that all
programmers are idiots and must have their hands held at all times?
Making an object parameter constant is something like babysitting.
Some pedants here seem to like it, but it is only for the use of the
programmer writing the function. Example:
int some_func(const int x)
{
/* body */
}
The programmer is expressing his intent not to change the value of the
int parameter 'x' inside the function, and is instructing the compiler
to warn him if he does so. It is not part of the function's
interface, and completely useless information to a caller of the
function, because the 'x' the function receives is a copy of the
caller's value, and changes made to it inside this function cannot
have any effect on any object in the caller.
Some people like this because it prevents a certain type of error,
namely when an argument is modified early in a function when code
later in a function expects it to retain the original value.
My response to that would be that if a function is long or complex
enough that such a mistake is easy to make and easy to overlook, the
function should be split into two or more smaller, simpler functions.
2. Used to alert the compiler that some kind of extra optimization is
possible, which wouldn't be possible if the data in question were
manipulated? And if so, exactly what sort of optimization would this
be?
The C standard does not define optimizations. There might well be
optimizations possible with data pointed to by a pointer to const, but
that is an implementation detail and off-topic here.
3. About as useful as a comment, with no other purpose but as a little
yellow sticky note saying "this function should act nondestructively on
this particular thing"?
No, it is far, far more useful than a comment, at least when talking
about pointers to const objects. Especially when used properly.
I always assumed it was some combination of 1 and 3 and so I tend to
never, ever use the thing...
Thanks, this is something I've always been curious about =)
Consider:
int my_strlen1(const char *x)
{
int count = 0;
while (*x)
{
++count;
++x;
}
return count;
}
int my_strlen2(char *x)
{
int count = 0;
while (*x)
{
++count;
++x;
}
return count;
}
int main(void)
{
const char *str = "Hello, World!";
int l1 = my_strlen1(str);
int l2 = my_strlen2(str);
puts(str);
return 0;
}
Your compiler should issue a diagnostic when you attempt to call
my_strlen2 with a pointer to const. And that's important, because the
pointer 'str' points to a string literal, and modifying a string
literal produces undefined behavior.
If you modify my_strlen1, say like this:
int my_strlen1(const char *x)
{
int count = 0;
while (*x)
{
++count;
*x = '?';
++x;
}
return count;
}
....the compiler will issue a diagnostic. To remove the diagnostic you
must remove the const qualifier. If your code is organized properly,
that is the same prototype is in scope at the definition and all calls
to a function, removing the const qualifier from the prototype will
cause a diagnostic when the caller sends a pointer to a string literal
to the function. And this is a good thing, because passing a string
literal to a function that attempts to modify it is a serious error
and causes undefined behavior.
--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://c-faq.com/
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.contrib.andrew.cmu.edu/~ajo/docs/FAQ-acllc.html
.
- Follow-Ups:
- Re: Whats the deal with 'const'?
- From: Tim Prince
- Re: Whats the deal with 'const'?
- From: Frederick Gotham
- Re: Whats the deal with 'const'?
- References:
- Whats the deal with 'const'?
- From: Snis Pilbor
- Whats the deal with 'const'?
- Prev by Date: Re: Whats the deal with 'const'?
- Next by Date: Re: Whats the deal with 'const'?
- Previous by thread: Re: Whats the deal with 'const'?
- Next by thread: Re: Whats the deal with 'const'?
- Index(es):
Relevant Pages
|