Const is not const

L

loudking

Hello all, please take a look at following code:

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char*argv[])
{
const char *c;
char *str= "const";

for(c=str; *c ; c++) {
printf("c=%c\n", *c);
}

return 0;
}

In this program, c is not const because in the for loop, c is
increamenting; *c is not const either because the output shows *c
equals different characters.

Then could anybody please tell me which part of variable c is
consistent anyway?
 
V

viza

Hi

const char *c;
char *str= "const";

for(c=str; *c ; c++) {
printf("c=%c\n", *c);

In this program, c is not const because in the for loop, c is
increamenting; *c is not const either because the output shows *c equals
different characters.

You are not changing what it pointed to by c, only making it point
somewhere else. What would be not allowed might be *c= 'z';

Also, you should have got a warning about c= str; Assigning a pointer to
a non-const type to a pointer to const type can confuse an optimising
compiler because it assumes what it is pointing to does not change.

In this case you could safely ignore such a warning (or prevent it by
using a cast) because you don't write to *str while *c is being read.

(also, const is "constant" not "consistant")

HTH
viza
 
J

Joachim Schmitz

viza said:
Hi



You are not changing what it pointed to by c, only making it point
somewhere else. What would be not allowed might be *c= 'z';

Also, you should have got a warning about c= str; Assigning a
pointer to a non-const type to a pointer to const type can confuse an
optimising compiler because it assumes what it is pointing to does
not change.

In this case you could safely ignore such a warning (or prevent it by
using a cast) because you don't write to *str while *c is being read.

(also, const is "constant" not "consistant")

And in C it's not even that, it is 'read only' instead.

Bye, Jojo
 
C

Chris Dollin

loudking said:
Hello all, please take a look at following code:

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char*argv[])
{
const char *c;
char *str= "const";

for(c=str; *c ; c++) {
printf("c=%c\n", *c);
}

return 0;
}

In this program, c is not const because in the for loop, c is
increamenting; *c is not const either because the output shows *c
equals different characters.

`const char *c` says that assignments of the form `*c = whatever`
are not legal.

`c` is not const, so different values may be assigned to it. `*c`
is const, because you're not allowed to update it. `*c` may take
on different values if `c` does.
Then could anybody please tell me which part of variable c is
consistent anyway?

(You meant "constant", not "consistent", yes?) The bit that says
"you can't update `*c`". "const" doesn't mean "constant", even
though that's how it starts and sort-of the reason it's there.
 
A

Andrey Tarasevich

loudking said:
int main(int argc, char*argv[])
{
const char *c;
> ...
}

Then could anybody please tell me which part of variable c is
consistent anyway?

No part of variable 'c' is "consistent" in a sense that you imply.
Variable 'c' itself is not a constant. You can change it in any way you
wish (as you do in you code).

The 'const' in the type of 'c' does not qualify pointer 'c' itself, but
rather restricts what you can do with what 'c' is pointing to. 'c' is
declared as 'pointing to a constant'. That means that 'c' provides you
with a constant access path to something, that you are not allowed to
use 'c' to modify what 'c' is pointing to. At the same time, what 'c' is
pointing to can possibly be changed through an alternative access path
(or by casting away the constness from 'c').
 
K

Kevin D. Quitt

const char *c;
In this program, c is not const ...

Correct - because you didn't declare it as const:

- cdecl
Type `help' or `?' for help
cdecl> explain const char *c
declare c as pointer to const char
cdecl> explain char * const c
declare c as const pointer to char
cdecl>
 
M

Martien Verbruggen

Hi



You are not changing what it pointed to by c, only making it point
somewhere else. What would be not allowed might be *c= 'z';

Also, you should have got a warning about c= str; Assigning a pointer to
a non-const type to a pointer to const type can confuse an optimising
compiler because it assumes what it is pointing to does not change.

Can you expand on this a bit more? For example, which compiler warns
about this? splint with no arguments doesn't warn about it. splint with
-strict-lib doesn't warn. Even with -strict-lib and -strict it doesn't
warn. neither does gcc with various options. I'd be interested to know
which compiler does warn, because I think it'd be an odd warning.

In this case you could safely ignore such a warning (or prevent it by
using a cast) because you don't write to *str while *c is being read.

I don't think that the compiler is free to use that optimisation. const
only restricts the use of the const qualified variable to read-only
access. It does not say anything about the memory the pointer points to.
That can still be changed by something else.

For this program:

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
const char *c;
char str[]= "foo";

c = str;
printf("'%c' ", *c);
*str = 'b';
printf("'%c'\n", *c);

return 0;
}

I think that a compiler would have to generate an executable that prints

'f' 'b'

to stdout, irrespective of the optimisation level.

Martien
 
V

viza

Hi

Can you expand on this a bit more? For example, which compiler warns
about this? splint with no arguments doesn't warn about it. splint with
-strict-lib doesn't warn. Even with -strict-lib and -strict it doesn't
warn. neither does gcc with various options. I'd be interested to know
which compiler does warn, because I think it'd be an odd warning.

The slightly overzealous one in my head, I think :-S.

viza
 
J

John Bode

Hello all, please take a look at following code:

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char*argv[])
{
        const char *c;
        char *str= "const";

        for(c=str; *c ; c++) {
                printf("c=%c\n", *c);
        }

        return 0;

}

In this program, c is not const because in the for loop, c is
increamenting; *c is not const either because the output shows *c
equals different characters.

Then could anybody please tell me which part of variable c is
consistent anyway?

Short answer:



const T * p -- in this case, p points to an object of type const T;
the pointer isn't constant, but the thing being pointed to is
constant. You can change where p points, but you cannot modify the
thing being pointed to.

T * const p -- in this case, p is a constant pointer to an object of
type T; the pointer is constant, but the thing being pointed to is not
constant. You cannot change where p points, but you can modify the
thing being pointed to.

So, in your code, you are allowed to change the value of c. However,
if you tried to modify what c was pointing to, like so:

for(c=str; *c ; c++) {
*c = toupper(*c);
printf("c=%c\n", *c);
}

the compiler would have issued a diagnostic. If you wanted c to point
to str and not point anywhere else, then you would have to write

char *str = "const";
char * const c = str;
 

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,997
Messages
2,570,241
Members
46,831
Latest member
RusselWill

Latest Threads

Top