const void * const x

C

codeslinger

What is the point of the construct in the subject line? Why the use of
two const labels? Does that do something different than const void *x?
And what would void * const x indicate? Thanks in advance :)
 
A

Artie Gold

codeslinger said:
What is the point of the construct in the subject line? Why the use of
two const labels? Does that do something different than const void *x?
And what would void * const x indicate? Thanks in advance :)

It means that neither the pointer nor what it points to may be changed.

HTH,
--ag
 
E

E. Robert Tisdale

Tobias said:
What is the point of the construct in the subject line?
Why the use of two const labels?

Both x and *x are constant.
Does that do something different than const void *x?
Yes.

And what would void * const x indicate?

It indicates that x is a constant.
> cat main.c
#include <stdio.h>
#include <stdlib.h>

int* ramp(size_t n) {
int* p = (int*)malloc(n*sizeof(int));
for (size_t j = 0; j < n; ++j)
p[j] = j;
return p;
}

int main(int argc, char* argv[]) {
const
size_t n = 32;
const
int* const p = ramp(n);
//p = NULL; // error! p is a constant
//p[0] = 13; // error! *p is a constant
for (size_t j = 0; j < n; ++j)
fprintf(stdout, "%2d = p[%2d]\n", p[j], j);
free((void*)p);
return 0;
}
> gcc -Wall -std=c99 -pedantic -o main main.c
> ./main
0 = p[ 0]
1 = p[ 1]
.
.
.
31 = p[31]
 
K

Keith Thompson

Artie Gold said:
It means that neither the pointer nor what it points to may be changed.

Right, but since it points to void, what it points to can't be changed
anyway.
 
E

E. Robert Tisdale

Keith said:
Right, but since it points to void,
what it points to can't be changed anyway.

#include <string.h>

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

Are you saying that memcpy cannot change what dest points to
just because dest is of type void*?
 
E

Emmanuel Delahaye

In 'comp.lang.c' said:
Right, but since it points to void, what it points to can't be changed
anyway.

Nonsense. A pointer can be aliased by a typed one. The point is that the
alias must be const too.

char s[] = "Hello"; /* R/W data */
void const *p = s; /* not dereferencable. */
char *pa = p; /* Diagnostic */
char const *pb = p; /* Correct. Read only acces */

For a more real approach, think in terms of parameters.
 
D

Dan Pop

In said:
#include <string.h>

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

Are you saying that memcpy cannot change what dest points to
just because dest is of type void*?

Nope, he's *obviously* saying that dest itself cannot be used for this
purpose: it has to be converted to an object pointer type first.

Dan
 
D

Dan Pop

In said:
Nonsense. A pointer can be aliased by a typed one.

But you're still not using the original pointer for this purpose. So,
where is the nonsense?!?
The point is that the alias must be const too.

If there is such a point, your example doesn't reflect it.
char s[] = "Hello"; /* R/W data */
void const *p = s; /* not dereferencable. */
char *pa = p; /* Diagnostic */
char const *pb = p; /* Correct. Read only acces */

I can't see any pointer aliasing another pointer in your example. Are
you sure you know what you're talking about? And what's incorrect with

char *pa = (char *)p;

? You can even use pa in write mode, because the pointed-to data is
modifiable. It didn't become read-only simply because you pointed a
pointer to const at it.

Far too often, using the type pointer to const means: "I promise not to
use this pointer to modify the data" rather than "this pointer points to
non-modifiable data". Just as in your example.

Dan
 
E

Emmanuel Delahaye

In said:
But you're still not using the original pointer for this purpose. So,
where is the nonsense?!?

<quote>
"but since it points to void, what it points to can't be changed anyway."
</>

This is wrong. It's not because a pointer is void that the pointed data is
not accessible, at least indirectly.
The point is that the alias must be const too.

If there is such a point, your example doesn't reflect it.
char s[] = "Hello"; /* R/W data */
void const *p = s; /* not dereferencable. */
char *pa = p; /* Diagnostic */
char const *pb = p; /* Correct. Read only acces */

I can't see any pointer aliasing another pointer in your example. Are
you sure you know what you're talking about?

I came with the idea that 'aliasing' was the result of more than one pointer
pointing to the same location. If you have a better definition, I'd be glad
to ear it.

Hence, in my example, 'pa' and 'pb' are aliasing 'p'. My wording might be
incorrect; correctness welcome.
char *pa = (char *)p;

Evil!
? You can even use pa in write mode, because the pointed-to data is
modifiable. It didn't become read-only simply because you pointed a
pointer to const at it.

Far too often, using the type pointer to const means: "I promise not to
use this pointer to modify the data" rather than "this pointer points to
non-modifiable data". Just as in your example.

Hehe! Abusive typecast users will burn in hell ;-)
 
K

Keith Thompson

In <[email protected]> "E. Robert Tisdale"


Nope, he's *obviously* saying that dest itself cannot be used for this
purpose: it has to be converted to an object pointer type first.

Right. On the other hand, a pointer to const void cannot be converted
to a pointer to non-const something-else without an explicit cast, so
the const qualifier in
const void *x;
is meaningful.
 
D

Dan Pop

In said:
<quote>
"but since it points to void, what it points to can't be changed anyway."
</>

This is wrong. It's not because a pointer is void that the pointed data is
not accessible, at least indirectly.

A pointer to void cannot, by definition, point to any data. It is not
a data pointer. It merely contains an address with no data type attached.
If you want to access any data, you need first to either convert it or
to alias it with a pointer to character type.
The point is that the alias must be const too.

If there is such a point, your example doesn't reflect it.
char s[] = "Hello"; /* R/W data */
void const *p = s; /* not dereferencable. */
char *pa = p; /* Diagnostic */
char const *pb = p; /* Correct. Read only acces */

I can't see any pointer aliasing another pointer in your example. Are
you sure you know what you're talking about?

I came with the idea that 'aliasing' was the result of more than one pointer
pointing to the same location. If you have a better definition, I'd be glad
to ear it.

You were talking about aliasing a pointer, not about aliasing the
pointed to data. See the underlined text above. As it happens, void
pointers can be aliased with character pointers, because they have the
same representation. A concrete example is left as an exercise to the
reader.
Hence, in my example, 'pa' and 'pb' are aliasing 'p'.

Nope. All three are aliasing the pointed data, when dereferenced.
My wording might be incorrect; correctness welcome.

It's your job to check your terminology, as this is not an
English-specific issue.

Just as evil as making p a pointer to const in the first place.
Hehe! Abusive typecast users will burn in hell ;-)

Except that there is no abuse here. The abuse was in using a pointer to
const in the first place! ;-)

Here's an example of abusive pointer casting:

const char *s = "Hello";
void const *p = s;
char *pa = (char *)p;

Can you understand the difference?

Try avoiding schematic/religious thinking and you'll become a much
better C programmer.

Dan
 
K

Keith Thompson

A pointer to void cannot, by definition, point to any data. It is not
a data pointer. It merely contains an address with no data type attached.
If you want to access any data, you need first to either convert it or
to alias it with a pointer to character type.

Or pass it to a function that takes a void* or const void* argument,
such as memcpy().

A pointer declared as
void *x;
can be passed as the first argument of memcpy(); a pointer declared as
const void *y;
cannot.

(The memcpy() function might convert it to char* internally, or it
might not even be implemented in C.)
 
D

Dan Pop

In said:
(e-mail address removed) (Dan Pop) writes:
[...]
A pointer to void cannot, by definition, point to any data. It is not
a data pointer. It merely contains an address with no data type attached.
If you want to access any data, you need first to either convert it or
to alias it with a pointer to character type.

Or pass it to a function that takes a void* or const void* argument,
such as memcpy().

Which accesses the data itself, but it still doesn't allow you access to
the data.
A pointer declared as
void *x;
can be passed as the first argument of memcpy(); a pointer declared as
const void *y;
cannot.

Irrelevant, as the address of to the *existing* data is memcpy's *second*
argument. It is obvious that you cannot use the address of a read only
object as the destination of a memory copy operation, no matter how it
is performed.

Dan
 
K

Keith Thompson

In said:
(e-mail address removed) (Dan Pop) writes:
[...]
A pointer to void cannot, by definition, point to any data. It is not
a data pointer. It merely contains an address with no data type attached.
If you want to access any data, you need first to either convert it or
to alias it with a pointer to character type.

Or pass it to a function that takes a void* or const void* argument,
such as memcpy().

Which accesses the data itself, but it still doesn't allow you access to
the data.

I don't see how that distinction is relevant.
Irrelevant, as the address of to the *existing* data is memcpy's *second*
argument.

I wasn't talking about memcpy's second argument, I was talking about
its first argument.
It is obvious that you cannot use the address of a read only
object as the destination of a memory copy operation, no matter how it
is performed.

Of course. Have I implied otherwise?

The point I was making was that the "const" keyword in "const void *y"
is semantically significant. I had previously said that "since it
points to void, what it points to can't be changed anyway"; I later
realized that this isn't entirely correct, since it can be changed by
passing the pointer to memcpy().
 
D

Dan Pop

In said:
[email protected] (Dan Pop) said:
In said:
(e-mail address removed) (Dan Pop) writes:
[...]
A pointer to void cannot, by definition, point to any data. It is not
a data pointer. It merely contains an address with no data type attached.
If you want to access any data, you need first to either convert it or
to alias it with a pointer to character type.

Or pass it to a function that takes a void* or const void* argument,
such as memcpy().

Which accesses the data itself, but it still doesn't allow you access to
the data.

I don't see how that distinction is relevant.

Too bad.
I wasn't talking about memcpy's second argument, I was talking about
its first argument.

Yet, memcpy uses its second argument to access the data, so as usual,
you're talking about something irrelevant to the discussion.
Of course. Have I implied otherwise?

The point I was making was that the "const" keyword in "const void *y"
is semantically significant.

Of course. Have I implied otherwise?

Dan
 
K

Keith Thompson

Yet, memcpy uses its second argument to access the data, so as usual,
you're talking about something irrelevant to the discussion.

I'm afraid I've lost track; what discussion is it irrelevant to? It
was entirely relevant to the point I was making (which was to correct
an error I made earlier). If you were having some other discussion,
perhaps you'd care to share it with the rest of us.
 
D

Dan Pop

In said:
I'm afraid I've lost track; what discussion is it irrelevant to? It
was entirely relevant to the point I was making (which was to correct
an error I made earlier). If you were having some other discussion,
perhaps you'd care to share it with the rest of us.

The discussion was about accessing data through void pointers. IIRC,
you correctly pointed out that void pointers cannot be used for this
purpose. Then, you lost track of the discussion and started talking
about other things.

Dan
 

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,145
Messages
2,570,825
Members
47,371
Latest member
Brkaa

Latest Threads

Top