Use of const in parameter specification

M

Martin

I've searched this newsgroup's archives but couldn't find any posts that
provided any "rule of thumb" recommendations for use of const in function
parameters.

I appreciate there is no need for scalar variables to have const defined,
but how far should it go with pointers?

The Standard Library has functions defined that specify const, for example,
puts(const char *s) but why not go the extra bit and make it puts(const char
* const s)?

Any recommendations with rationale gratefully received.
 
M

Martin Dickopp

Martin said:
I've searched this newsgroup's archives but couldn't find any posts that
provided any "rule of thumb" recommendations for use of const in function
parameters.

I appreciate there is no need for scalar variables to have const defined,
but how far should it go with pointers?

The Standard Library has functions defined that specify const, for example,
puts(const char *s) but why not go the extra bit and make it puts(const char
* const s)?

Any recommendations with rationale gratefully received.

`const char *s' means that the memory pointed to by `s' cannot be
modified through `s'. In the context of a function prototype, you can
consider this a promise: The function `puts' promises not to modify
the string you pass as argument.

`char *const s' means that the pointer itself cannot be modified. But
remember that `puts' has its own copy of the pointer. The caller doesn't
need to know if `puts' modifies its copy of the pointer, since that
wouldn't have any influence on the caller anyway.

For this reason, const (and volatile, and [in C99] restrict) qualifiers
on the parameter itself (but not on what the parameter points to, if it
is a pointer) can always be omitted in prototype declarations. It is
valid to declare, e.g., the following prototype

void foo (int a, int *b, const int *const *c);

and then define the function as

void foo (const int a, int *const b, const int *const *const c)
{
/* ... */
}

Martin
 
M

Martin Dickopp

Martin Dickopp said:
`char *const s' means that the pointer itself cannot be modified. But
remember that `puts' has its own copy of the pointer. The caller doesn't
need to know if `puts' modifies its copy of the pointer, [...]
^^^^^^^^
My statement was a bit ambiguous. In case it's not clear from the
context: The underlined text refers to the copy of the pointer in the
`puts' function, /not/ the copy in the caller.

Martin
 
M

Mark McIntyre

I've searched this newsgroup's archives but couldn't find any posts that
provided any "rule of thumb" recommendations for use of const in function
parameters.

I appreciate there is no need for scalar variables to have const defined,
but how far should it go with pointers?

if a function doesn't modify the contents of a pointer argument, then make
it const to a) remind the function maintainer not to try and b) inform the
caller that its safe to assume its unchanged.
The Standard Library has functions defined that specify const, for example,
puts(const char *s) but why not go the extra bit and make it puts(const char
* const s)?

That says that the pointer itself is unchangeable. There's no benefit in
that since the fn gets a copy of the pointer anyway, and changing the copy
won't have any effect on the caller.
 
D

Dan Pop

In said:
`const char *s' means that the memory pointed to by `s' cannot be
modified through `s'.

Of course it can:

*(char *)s = 'a';

It need not even invoke undefined behaviour, depending on where s actually
points.
In the context of a function prototype, you can
consider this a promise: The function `puts' promises not to modify
the string you pass as argument.

A "promise" only to the human reader: the compiler still cannot rely on it
when optimising, for the above shown reason.

Dan
 
M

Martin O'Brien

Mark said:
That says that the pointer itself is unchangeable. There's
no benefit in that since the fn gets a copy of the pointer
anyway, and changing the copy won't have any effect on
the caller.

I suppose the only benefit is to trap any inadvertent attempts to
change that local pointer, indicating that the author is attempting
something he or she shouldn't.

Martin
http://martinobrien.co.uk/
 
M

Martin Dickopp

I suppose the only benefit is to trap any inadvertent attempts to
change that local pointer, indicating that the author is attempting
something he or she shouldn't.

That's not achieved by making the pointer const in the prototype
declaration, unless the declaration is also the definiton. Only
the qualifier in the definition counts, while the qualifier in the
(non-definition) prototype declaration will be ingored.
 
M

Martin

Martin Dickopp said:
That's not achieved by making the pointer const in the prototype
declaration, unless the declaration is also the definiton. Only
the qualifier in the definition counts, while the qualifier in the
(non-definition) prototype declaration will be ingored.

Thanks for that Martin.

I'm only talking about the function definition.
 

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

No members online now.

Forum statistics

Threads
474,140
Messages
2,570,810
Members
47,357
Latest member
sitele8746

Latest Threads

Top