why const-qualify a pointer?

N

Nnaemeka David

For what reasons should a pointer be const-qualified? Take this example:
char * cont s1;
since a pointer is supposed to be referring to a variable's address or value, I wonder why a reference should be constant? i do understand this statement though:
const char * s2;
a pointer to a constant-qualified char type. thanks.
 
J

James Kuyper

For what reasons should a pointer be const-qualified? Take this example:
char * cont s1;
since a pointer is supposed to be referring to a variable's address or value, I wonder why a reference should be constant? i do understand this statement though:
const char * s2;
a pointer to a constant-qualified char type. thanks.

The advantage to const-qualifying a pointer (if there is such an
advantage) is the same as for const-qualifying anything else. It
documents your belief that the thing so-qualified is not supposed to be
changed, in a way that mandates a diagnostic message if you make the
mistake of writing code that might try to change it. Not every way of
writing such code will produce such a diagnostic, so the protection is
less than perfect - but there's a lot of ways that will. When you get
such a diagnostic, it means one of two things; either the pointer should
not have been const-qualified, or the code should not have tried to
change its value.
This obviously does not apply to a pointer whose value should be subject
to change.
 
M

Malcolm McLean

For what reasons should a pointer be const-qualified? Take this example:

char * cont s1;

since a pointer is supposed to be referring to a variable's address or value, > I wonder why a reference should be constant? i do understand this statement
though:

const char * s2;

a pointer to a constant-qualified char type. thanks.
const means "don't write to me". It's a confusing name because const pointers
usually do refer to RAM which is written in other parts of the program.

const is a bit controversial. Denis Ritchie, the inventor of C, didn't like
it. It makes functions like strchr() difficult to write. It also means that
every subroutine also has to take a const, which adds visual clutter to code.
Then whilst the pointer itself points to const memory, it's impossible to
specify that everything pointed to it indirectly is in constant memory,
which limits its usefulness.
void payroll(const EMPLOYEE *employee)
{
if(!strcmp(employee->nmae, "Fred"))
strcpy(employee->name, "Ha ha Fred is dead");
}

is legal, which is confusing.

But it does document that the function doesn't write to the const *, it
can protect ROM, it can also help with the pointer aliasing problem.
 
B

BartC

which limits its usefulness.
void payroll(const EMPLOYEE *employee)
{
if(!strcmp(employee->nmae, "Fred"))
strcpy(employee->name, "Ha ha Fred is dead");
}

is legal, which is confusing.

But it does document that the function doesn't write to the const *, it
can protect ROM, it can also help with the pointer aliasing problem.

ROM has got its own built-in protection!

(Actually one very early technique I used, to protect a block of RAM from a
program going haywire, was a toggle switch on the /WR line, making writing
impossible. Handy because that's where the source code was stored, in the
absence of a disk drive.)
 
R

Rosario1903

For what reasons should a pointer be
const-qualified? Take this example:
char * cont s1;
since a pointer is supposed to be referring to a variable's
address or value, I wonder why a reference should be
constant? i do understand this statement though:
const char * s2;
a pointer to a constant-qualified char type. thanks.

for me there is no pratical reason,
const has to not exist

they invent reason where there are not
 
K

Keith Thompson

BartC said:
which limits its usefulness.

ROM has got its own built-in protection!

(Actually one very early technique I used, to protect a block of RAM from a
program going haywire, was a toggle switch on the /WR line, making writing
impossible. Handy because that's where the source code was stored, in the
absence of a disk drive.)

At least on hosted implementations, user data is rarely if ever stored
in ROM (read-only memory). Some user data may be stored in a segment of
RAM (random access read/write memory) that's protected from modification
by the operating system.
 
A

Andrew Cooper

for me there is no pratical reason,
const has to not exist

they invent reason where there are not

const is fantastically useful for showing an intention that data should
be read only.

See
http://xenbits.xen.org/gitweb/?p=xen.git;a=commitdiff;h=42c5b1214071d363a52c6356dfe2ed820f500849
as a perfect (and recent, which is why it comes to mind) example of a
bug introduced because a pointer was not const when it really should
have been.

const is there for you to help the compiler to help you not make mistakes.

This doesn't help the "special" programmers who blindly cast away
const-ness in an effort to make things compile, but it will help a
careful programmer to notice that they have made a mistake, or need to
change the API.

~Andrew
 
I

Ian Collins

Rosario1903 said:
for me there is no pratical reason,
const has to not exist

they invent reason where there are not

There are many and I'm sure you know that all too well.

Have you ever tried writing to read only memory?
 
R

Rosario1903

const is fantastically useful for showing an intention that data should
be read only.

See

i followed that link, i not had understood too much...
if you can show where is the problem with few line of easy code here
ok
as a perfect (and recent, which is why it comes to mind) example of a
bug introduced because a pointer was not const when it really should
have been.

i pheraps because the few code i wrote, never had problem in not using
const... if there are place where i have not to write, or better i
have to write there only *one* time: i write it in comments

but in my life that case never happen
const is there for you to help the compiler to help you not make mistakes.

i not believe in const
This doesn't help the "special" programmers who blindly cast away
const-ness in an effort to make things compile, but it will help a
careful programmer

who is careful? are you? are the one that propose const?
 
B

BartC

Ian Collins said:
Rosario1903 wrote:

There are many and I'm sure you know that all too well.

Have you ever tried writing to read only memory?

There might be many uses but that doesn't sound like a particularly useful
one.

(It doesn't help that C's convoluted type-specification syntax makes it
difficult to see whether it it the pointer that is read-only, or what it
points to. That, and the extra clutter that 'const' introduces, partly
explains why I've never used 'const' and would not miss it if it didn't
exist.)
 
J

Jorgen Grahn

.
(It doesn't help that C's convoluted type-specification syntax makes it
difficult to see whether it it the pointer that is read-only, or what it
points to. That, and the extra clutter that 'const' introduces, partly
explains why I've never used 'const' and would not miss it if it didn't
exist.)

Of course it's up to you, but isn't that a rather career-limiting
decision? People generally use const and expect others to do it, too.

/Jorgen
 
S

Seebs

if you can show where is the problem with few line of easy code here
ok

I think that's sort of the point: This is a code maintenance issue, which
means it tends to become significant only when you get to larger projects.
i not believe in const

I don't think this matters.
who is careful? are you? are the one that propose const?

I definitely didn't propose it, and I sort of dislike it. But I use it
now because I've learned that it results in the compiler catching things
that I didn't think through carefully enough, or where I'd simply forgotten
things.

The basic issue: Some functions which take a pointer want to modify
the thing pointed to. Some don't. Sometimes, I have a thing which I wouldn't
mind having the code modify, sometimes, I really don't want it modifying
the thing. If I don't have a 100% perfect memory of which functions are
which, I am likely to occasionally pass a pointer to data I don't want
modified into a function which will modify data.

If I use const qualifiers consistently, that gets me an error at compile
time which allows me to evaluate it and determine what I forgot this time.
Usually, it turns out that indeed it is the case that I forgot about
a side-effect, or forgot that a given object needed to be not-modified by
my code. And that means that const has caught something that would otherwise
have been a very mysterious and possibly sporadic failure at runtime.

-s
 
M

Malcolm McLean

The basic issue: Some functions which take a pointer want to modify
the thing pointed to. Some don't. Sometimes, I have a thing which I wouldn't
mind having the code modify, sometimes, I really don't want it modifying
the thing.
But consider this.

bool connected(const unsigned char *binaryimage, int width, int height, int x1, int y1, int x2, int y2)

it's naturally const. We want to detect whether x1,y1 and x2,y2 are connected
by a path of set pixels. We don't want to modify the data.
But how are we to write that function? There are a handful of algorithms, but a
simple and reasonably fast one is to floodfill x1,y1 and test x2,y2. You can
use a double seed and spiral fill if you want to be a bit more efficient,
but the idea is the same.

You can create a temporary buffer, but it's a lot of work, copying the entire
image each time for what may be usually testing points only a few pixels
apart. And you've got handle a possible out of memory condition. it's a lot
easier simply to floodfill into the buffer and then floodfill again to set it
back. Caller needs to know that binary image is in the same state when it
started as on function end, but unless he's calling in a threaded environment
and sharing data, he doesn't need to know what you do in the interim.
 
S

Seebs

But consider this.
bool connected(const unsigned char *binaryimage, int width, int height, int x1, int y1, int x2, int y2)
it's naturally const. We want to detect whether x1,y1 and x2,y2 are connected
by a path of set pixels. We don't want to modify the data.
But how are we to write that function? There are a handful of algorithms, but a
simple and reasonably fast one is to floodfill x1,y1 and test x2,y2. You can
use a double seed and spiral fill if you want to be a bit more efficient,
but the idea is the same.
You can create a temporary buffer, but it's a lot of work, copying the entire
image each time for what may be usually testing points only a few pixels
apart. And you've got handle a possible out of memory condition. it's a lot
easier simply to floodfill into the buffer and then floodfill again to set it
back.

Uh. That's a destructive change, if the thing you floodfilled too happens to
already occur anywhere in the buffer, and it sounds pretty expensive to me.
Caller needs to know that binary image is in the same state when it
started as on function end, but unless he's calling in a threaded environment
and sharing data, he doesn't need to know what you do in the interim.

Unless there's some other reason for which that image might not be in
writeable memory. Which happens.

-s
 
B

BartC

bool connected(const unsigned char *binaryimage, int width, int height,
int x1, int y1, int x2, int y2)
You can create a temporary buffer, but it's a lot of work, copying the
entire
image each time for what may be usually testing points only a few pixels
apart. And you've got handle a possible out of memory condition. it's a
lot
easier simply to floodfill into the buffer and then floodfill again to set
it
back.

How does that work? Suppose the image is all white except for a black square
in the middle, and the two points are in that square. Once it's floodfilled
to white, the boundaries of the square have disappeared.
 
M

Malcolm McLean

Uh. That's a destructive change, if the thing you floodfilled too happens to
already occur anywhere in the buffer, and it sounds pretty expensive to me.
No, the algorithm goes

floodfill(binaryimage, target = 1, fill = 2, pos = x1, y1);
if (binaryimage[x2, y2] == 2)
answer = true;
floodfill(binaryimage, target = 2, fill =1, pos = x1, y1);

so we floodfill from x1,y1, setting all the set pixels to 2. So if x2, y2 is
connected to x1,y1, it will become a 2. Then we floodfill back to 1 to restore
the binary image.

Obviously if we want a really cheap function we'll have to be cleverer with
the initial floodfill. It's only efficient if you've an environment where you
have lots of discrete patches of set pixels. But we'll still want to write to
an image buffer, almost certainly, basically you go out in a spiral from
the two points filling, and then stop when you hit a pixel filled from the
other seed (connected) or run out of edge pixels (not connected).
 
S

Seebs

No, the algorithm goes
floodfill(binaryimage, target = 1, fill = 2, pos = x1, y1);
if (binaryimage[x2, y2] == 2)
answer = true;
floodfill(binaryimage, target = 2, fill =1, pos = x1, y1);
so we floodfill from x1,y1, setting all the set pixels to 2. So if x2, y2 is
connected to x1,y1, it will become a 2. Then we floodfill back to 1 to restore
the binary image.

Okay, let's imagine we want to do something like this, and we want to tell
whether the top left and bottom right locations are connected:

11101112
10110100
11100102
01111111

So we do the fill. Since all the 1s are in fact connected, they all turn into
2s.

22202222
20220200
22200202
02222222

Now we do another flood fill, changing the connected 2s back to 1s:

11101111
10110100
11100101
01111111

Notice that the two locations which were *already* 2s before we started
have been changed.

The algorithm is destructive. Flood-fill is not a reversible operation.

Performance doesn't even enter into it; doing a flood fill to change it
back does not produce the original state, so this is a really good argument
FOR the const qualifier being used and honored -- because otherwise
someone will think of a "clever" algorithm which they think doesn't change
the data, and be wrong.

-s
 
B

BartC

The algorithm is destructive. Flood-fill is not a reversible operation.

It might be workable if a special flood-fill colour can be used that is not
part of the picture (although obviously not possible on a 2-level image).

Or it's possible a second image is created, which need only be 1-bit per
pixel. Then the flood-fill algorithm only writes to this image, setting
pixels from 0 to 1. The two points are connected when x2,y2 is set to '1' in
this image.

This second image will likely use much less memory, only needs clearing to
zeros, not copying, and it is not necessary to run flood-fill again at the
end. And you can use 'const' on the original...
 
B

Ben Bacarisse

BartC said:
It might be workable if a special flood-fill colour can be used that is not
part of the picture (although obviously not possible on a 2-level image).

Or it's possible a second image is created, which need only be 1-bit per
pixel. Then the flood-fill algorithm only writes to this image, setting
pixels from 0 to 1. The two points are connected when x2,y2 is set to '1' in
this image.

This second image will likely use much less memory, only needs
clearing to zeros, not copying, and it is not necessary to run
flood-fill again at the end. And you can use 'const' on the
original...

Or you can replace the function with "return 1;"! You've lost track of
the purpose. If the image is cleared, all points will appear connected.
 
M

Malcolm McLean

Okay, let's imagine we want to do something like this, and we want to tell
whether the top left and bottom right locations are connected:


11101112
10110100
11100102
01111111
A binary image has set/unset pixels. So passing a value other than 1 or 0
results in undefined behaviour.
Why not pass as a packed bitmask? Partly because it makes it easy to
implement functions liked connected() efficiently.
 

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,769
Messages
2,569,578
Members
45,052
Latest member
LucyCarper

Latest Threads

Top