|feature wanted: detect missing 'const' firstname.lastname@example.org (1994-03-16)|
|Re: feature wanted: detect missing 'const' email@example.com (1994-03-23)|
|Re: feature wanted: detect missing 'const' Mark.Lomas@cl.cam.ac.uk (1994-03-25)|
|partial const'ness (was feature wanted: detect missing 'const') dfb@beech.CS.Berkeley.EDU (1994-03-28)|
|Re: feature wanted: detect missing 'const' firstname.lastname@example.org (1994-03-29)|
|Keywords:||C++, lint, comment|
|Organization:||University of Cambridge Computer Laboratory|
|Date:||Fri, 25 Mar 1994 13:44:53 GMT|
email@example.com (John Reiser) writes:
>[have compiler warn when const could have been used but wasn't]
Bill Leonard <firstname.lastname@example.org> wrote:
>Actually, I've felt for some time that 'const' was actually the wrong
>concept, at least for formal arguments of functions.
>Of course, it's really too late for C and C++ to get this right. But
>maybe some future language could.
I agree with Bill however the problem is in part due to the way that C
mixes two different concepts. I'm only singling out C since I'm familiar
with it - this doesn't mean that it is, necessarily, worse than other
languages currently in use.
When I declare a function that takes a pointer as a parameter
void Munge(char *string);
there are several reasons why I might have chosen to use a pointer. Here
the name "string" implies part of the reason - I can't pass indefinite
strings other than by pointer. A similar pointer might reference only one
character that the function intends to pass back to the caller. It might
reference a multiple character string that is to be passed back to the
The concepts that C mixes up are the intention of the user and the
implementation. I would like to divorce these concepts from each other.
For example when writing a routine I might intend to modify the caller's
copy of a parameter. In other languages I might declare the formal
parameter as "var", "out", or "in_out". C programmers take it for granted
that they pass a pointer. This has no business appearing in the source,
it is an aspect of the implementation.
Consider the following procedure header in Pascal
procedure Munge(var c : char);
Like the C header it tells us that the parameter is a character that may
be modified by the callee. It has the slight benefit that it does not
threaten to modify the characters that may follow it in memory. A major
advantage to my mind is that the compiler may choose to return the
parameter to the caller in a register. The C implementation hinders
certain optimisation. Of course a Pascal implementation is free to pass a
pointer if it wants - the declaration is not constraining.
Pointers also affect the level of abstraction. Imagine I declare my own
data type and a set of operations that act upon it. I pass an actual
parameter of this type to some function.
void Munge2(const MyType thingy);
What does the "const" keyword promise? I would like the abstraction to be
similar to the predefined types - "const" might promise that the function
Munge2 will not change the value of the actual parameter. In a certain
sense this is what it does, unfortunately it is possible that the value of
"thingy" contains pointers to objects that the function may modify.
The pointers found inside a structure (here Pascal is almost as guilty as
C) are an aspect of the implementation rather than the programmer's
intent. If I create a list in C or Pascal why should I need to know
whether it is implemented as a linked list with pointers, a dynamic array,
or whatever the compiler deems most appropriate. I'm not saying that we
never need to know but that I object to the idea that we always need to
To see why the level of abstraction is important let us consider a more
specific data type. Let's imagine that I have a list of keywords, say the
list of reserved words in the language I'm compiling. As a programmer my
intent is that the value of the actual parameter is the list itself. C
imposes a different level of abstraction claiming that the actual value is
the header of the list and the rest of the list is fair game (i.e. the
"const" keyword doesn't protect the rest). Pascal requires the programmer
to know the implementation of the data type since if it is a linked list
it is treated like in C but if it is an array then it is treated more like
the programmer intended.
My plea to language designers and compiler writers is to ask that formal
parameters express the intent of the programmer and, except where the
programmer wishes, avoids any indication of the implementation. In
particular "var" or "out" parameters should not require pointers, although
I have no objection if the underlying implementation chooses to use them.
Could those who think that pointers are acceptable please explain how to
declare a formal parameter that is passed from the caller to the callee in
a register, the value is changed by the callee and returned to the caller
in the same register.
[I suppose in C++ that'd be "register int& foo" -John]
Return to the
Search the comp.compilers archives again.