In article <47***********************@free.teranews.com>
Ben Petering <bj*@dfmagicp.orgwrote:
>this is a 'best practice' type question (I want discussion of the issue
- whys and why nots - similar to "casting the return value of malloc()",
to cite an analogous case).
Let's say I have a function written in assembler/(some non-C language)
which takes one pointer-to-const-char arg, the declaration being:
extern unsigned int str_len(const char *s);
Is the 'const' type qualifier 1) advisable and 2) legal?
It is definitely "legal" (a poorly-specified term, but no matter how
*you* are using it, I think it comes out the same ... of course it is
possible that none of the interpretations I am guessing at are the one
you intended). As for "advisable", that depends.
>The C compiler has no way of enforcing what a non-C function does with
the pointer,
Indeed -- but it has no way of enforcing what a C function does either:
void icky(const int *p) {
*(int *)p = 42;
}
is valid C code, with no diagnostic required. I would call this
"inadvisable" though. :-)
>and as I understand it, the type qualifier is a guarantee of sorts - the
compiler guarantees said l-value will not be modified using the passed
pointer.
No, there is no such guarantee (see icky() above). It does tend
to promise a human reader that the function will not modify *s,
though. The main thing that it (this const) does, in a C compiler,
is make calls that pass const-qualified pointers semantically
correct, so that no diagnostic is required.
I think this is far clearer when shown by example. Suppose we are
writing some C code and are working on some intermediate or top level
function:
void something(const char *str) {
unsigned int val;
... do some work ...
val = str_len(str); /* note this line */
... do more work ...
}
For whatever reason (good or bad) our function, something() in this
case, takes a "const char *" value. It then calls the assembly
str_len(), passing the pointer value "str" on. If you change the
declaration for str_len() to take plain (non-const-qualified)
"char *", the call at the "noted" line now violates a constraint,
and a diagnostic is required.
If something() is an intermediate-level function, and we want to
call it as follows, then having something() take "const char *" is
"good" because one of the following calls provides a pointer to
"const char":
const char const_buf[] = "hello";
char modifiable_buf[] = "world";
...
something(const_buf);
something(modifiable_buf);
It is OK to "add" a const qualifier (but only a "top level" one;
see the comp.lang.c FAQ for details; C gets this wrong while C++
gets it right) in a call, but it is not OK to remove one. This is
(presumably) why something() takes a "const char *", and if
something() needs to call str_len(), and str_len() will not modify
the chars involved, including the qualifier in the declaration for
str_len() is probably a good idea.
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
email: forget about it
http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.