const pointers

F

FtM

Hello.
I was updating some code trying to enforce the use of "const"
modifiers, and I came up with some strange doubts.
First of all:
If I have a:
const void *p;
I can read and write the data pointed by p, but I cannot modify the
value of the pointer itself, while with a:
void * const p;
I can modify the pointer value but not the data it points to.
So a:
const void * const p;
gives me a completely "locked" pointer.
Is it right?

If I am right, why some standard functions have inconsistent
prototypes? For example, memcpy:
void *memcpy(void *s1, const void *s2, size_t n);
shouldn't it be:
void *memcpy(const void *s1, const void *const s2, size_t n);
?
Am I missing something?

Thank you for your answers!
 
E

Eric Sosman

Hello.
I was updating some code trying to enforce the use of "const"
modifiers, and I came up with some strange doubts.
First of all:
If I have a:
const void *p;
I can read and write the data pointed by p, but I cannot modify the
value of the pointer itself,

No, that's wrong. For one thing, you can't read or write through
a void* at all, with or without const. Change to `const char *p;' and
you'll find that you *can* change the value of p itself, but *cannot*
change what it points to:

int main(void) {
char hello[] = "Hello";
const char *p = hello;
*p = 'J'; /* what does your compiler say? */
p += 1; /* what does your compiler say? */
return 0;
}
while with a:
void * const p;
I can modify the pointer value but not the data it points to.

No, with this one you *cannot* modify the pointer, but *can*
modify the target. Change the declaration in the program above,
and once again see what your compiler thinks.
So a:
const void * const p;
gives me a completely "locked" pointer.
Is it right?

Yes; this version carries both prohibitions: You cannot modify
the pointer variable p, and you cannot modify its target.
If I am right, why some standard functions have inconsistent
prototypes? For example, memcpy:
void *memcpy(void *s1, const void *s2, size_t n);
shouldn't it be:
void *memcpy(const void *s1, const void *const s2, size_t n);
?
Am I missing something?

Yes: You're confused about which `const' appearances affect the
variable and which affect the target.
 
V

Vincenzo Mercuri

FtM ha scritto:
Hello.
I was updating some code trying to enforce the use of "const"
modifiers, and I came up with some strange doubts.
First of all:
If I have a:
const void *p;
I can read and write the data pointed by p, but I cannot modify the
value of the pointer itself, while with a:
void * const p;
I can modify the pointer value but not the data it points to.
So a:
const void * const p;
gives me a completely "locked" pointer.
Is it right?

If I am right, why some standard functions have inconsistent
prototypes? For example, memcpy:
void *memcpy(void *s1, const void *s2, size_t n);
shouldn't it be:
void *memcpy(const void *s1, const void *const s2, size_t n);
?
Am I missing something?

Thank you for your answers!

When you write:

const void *p;

it means that you *can't* modify /*p/, but you *can* modify /p/;
you can call it /pointer to constant data/ or /read-only pointer/.
With:

void * const p;

you *can't* modify /p/ but you *can* modify /*p/;
you can call it /constant pointer/.

Now, memcpy has the prototype:

void *memcpy(void *dest, const void *src, size_t len);

and actually it allows you to *read* from *src and
*write* to *dest, so it's exactly what you would need to do.
 
F

FtM

Hello.
I was updating some code trying to enforce the use of "const"
modifiers, and I came up with some strange doubts.
First of all:
If I have a:
const void *p;
I can read and write the data pointed by p, but I cannot modify the
value of the pointer itself,

     No, that's wrong.  For one thing, you can't read or write through
a void* at all, with or without const.  Change to `const char *p;' and
you'll find that you *can* change the value of p itself, but *cannot*
change what it points to:

        int main(void) {
            char hello[] = "Hello";
            const char *p = hello;
            *p = 'J';    /* what does your compiler say? */
            p += 1;      /* what does your compiler say? */
            return 0;
        }
while with a:
void * const p;
I can modify the pointer value but not the data it points to.

     No, with this one you *cannot* modify the pointer, but *can*
modify the target.  Change the declaration in the program above,
and once again see what your compiler thinks.
So a:
const void * const p;
gives me a completely "locked" pointer.
Is it right?

     Yes; this version carries both prohibitions: You cannot modify
the pointer variable p, and you cannot modify its target.

Yes, I'm sorry, I just switched the two definitions - You are
completely right.
     Yes: You're confused about which `const' appearances affect the
variable and which affect the target.

Well, the "question" still remains: why not having a:
void *memcpy(void * const s1, const void *const s2, size_t n); ?
memcpy will not change s1 but only the data it points to, and will not
touch s2 at all.
 
B

Ben Bacarisse

FtM said:
Well, the "question" still remains: why not having a:
void *memcpy(void * const s1, const void *const s2, size_t n); ?
memcpy will not change s1 but only the data it points to, and will not
touch s2 at all.

Every library function could have const parameters but there would be no
gain. There is nothing special about pointers in this regard -- you
should, to be consistent, have made n const as well.

No change can ever bee seen by the caller so only the writer of a
function cares if the parameters are const or not. It would simply
complicate the prototype. For example in C99 it would then become:

void *memcpy(void * restrict const s1,
const void * restrict const s2,
const size_t n);

all for no gain to the programmer using memcpy.
 
F

FtM

Every library function could have const parameters but there would be no
gain.  There is nothing special about pointers in this regard -- you
should, to be consistent, have made n const as well.

No change can ever bee seen by the caller so only the writer of a
function cares if the parameters are const or not.  It would simply
complicate the prototype.  For example in C99 it would then become:

  void *memcpy(void * restrict const s1,
               const void * restrict const s2,
               const size_t n);

all for no gain to the programmer using memcpy.

I got it. The "caller" pointer could not be modified anyway inside the
function.
Well, it was simple after all :)
Thank you very much!
 
K

Keith Thompson

Ben Bacarisse said:
Every library function could have const parameters but there would be no
gain. There is nothing special about pointers in this regard -- you
should, to be consistent, have made n const as well.

No change can ever bee seen by the caller so only the writer of a
function cares if the parameters are const or not. It would simply
complicate the prototype. For example in C99 it would then become:

void *memcpy(void * restrict const s1,
const void * restrict const s2,
const size_t n);

all for no gain to the programmer using memcpy.

And it wouldn't allow the function body to modify its own parameters,
which are local objects (assuming the body is written in C, and
assuming the prototype in the declaration and in the definition
are consistent).
 
B

Ben Bacarisse

Keith Thompson said:
And it wouldn't allow the function body to modify its own parameters,
which are local objects (assuming the body is written in C, and
assuming the prototype in the declaration and in the definition
are consistent).

That depends on what you mean by consistent. If you mean "the same"
then I agree, but if you mean compatible (in the C sense) then no. I'd
say that the prototype given above is consistent with a definition like
this:

void *memcpy(void *restrict s1, const void *restrict s2, size_t n)
{
/* ... */
}

because the type types are compatible. That, to me, seems like the
obvious way to determine if the prototype and the definition are
consistent.

Anyway, my point is that the prototype does not prevent the function
being written in C with non-const parameters.
 
K

Keith Thompson

Ben Bacarisse said:
Keith Thompson <[email protected]> writes:

[Context: Declaring parameters const]
That depends on what you mean by consistent. If you mean "the same"
then I agree, but if you mean compatible (in the C sense) then no.

I meant "the same".

[snip]
Anyway, my point is that the prototype does not prevent the function
being written in C with non-const parameters.

Personally, I prefer the parameter declarations in the declaration
and definition to be identical, but you're right, C doesn't
require that.
 
B

Barry Schwarz

No, that's wrong. For one thing, you can't read or write through
a void* at all, with or without const.

People who use fread and fwrite are going to be surprised, along with
all those who use the mem... functions.
 
E

Eric Sosman

On Thu, 08 Jul 2010 08:53:36 -0400, Eric Sosman


People who use fread and fwrite are going to be surprised, along with
all those who use the mem... functions.

I wrote that "you," meaning "the C programmer," cannot read
or write through a void*. The library functions need not be
written in C and thus are not constrained by the rules of C.
They can do a lot of magical things that C unaided cannot, and
this may include the ability to read and write through void*
pointers. (Although if the implementation language is not C it
is not at all clear that they can be called "void*", or even
"pointers.")

In the very common case that at least some of these void*-
accepting functions are written in C, I think you'll find that
they use their void* parameters only as values with which to
initialize pointers of other types. They cannot, however, read
or write through the void* itself.
 

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
473,770
Messages
2,569,583
Members
45,074
Latest member
StanleyFra

Latest Threads

Top