4

Below is the implementation of strlen.c as per "The Standard C Library,

size_t strlen(const char *s){
   const char *sc;
   for(sc = s; *sc != '\0'; ++sc)

   return (sc-s);  }

Is my understanding of the legality of sc = s correct?

sc=s is a legal assignment because since both variables are declared as const, both protect the object that is pointed to by s. In this case, it is legal to change where sc or s both point to but any assignment (or reference?) to *s or sc would be illegal.

Keith Thompson
  • 254,901
  • 44
  • 429
  • 631
M.A.A
  • 79
  • 1
  • 4

3 Answers3

5

I think what you are asking is what the const keyword means. If not please clarify your question.

The way I like to think of it is any const variable can be stored in ROM (Read Only Memory) and variables that are not declared const can be stored in RAM (Random Access Memory). This kind of depends on the kind of computer you are working with so the const data may not actually be stored in ROM but it could be.

So you can do anything you want with the pointer itself but you can not change the data in the memory it points to.

This means you can reference the pointer and pass that around as much as you like. Also you can assign a different value to the pointer.

Say you have this code

const char* foo = "hello";
const char* bar = "world";

Its perfectly legal to do

foo = bar;

Now both point "world"

Its also legal to do

const char *myPtr = bar;
myPtr = foo;

What you are not allowed to do is change the actual data memory so you are not allowed to do

foo[0] = 'J';
Marc
  • 1,159
  • 17
  • 31
2

You are correct.

const char * sc declares a pointer to a const char. In essence, it means that sc points to a variable of type char (or in that case, a contiguous array of chars) and that you cannot use sc to modify the pointed variable. See it live here.

Note that sc itself is not a const variable. The const applies to the pointed variable, and not to the pointer. You can thus change the value of the pointer, i.e. the variable to which it points.

Follow this answer to have more insight about the different uses of const and pointers : What is the difference between const int*, const int * const, and int const *?

Louen
  • 3,617
  • 1
  • 29
  • 49
  • "The const applies to the pointed variable...", so in the case of `sc=s`, does the const from `const char sc` apply to `s` or the value of `s`. In my answer I presumed both const declarations apply to the ultimate value of the pointers but now I am not so sure. Ie if it were to apply to s, then after declaring `sc=s` it would become illegal to change what s points to. – M.A.A Jan 16 '19 at 00:36
  • @M.O. The assignment shouldn't change anything. Both variables are declared as pointers to constant chars, so the value they point to is constant while the pointers themselves aren't. Since the assignment assigns the pointers and not the memory they point to, the code is legal. To make the pointers constant, you would put `const` after the `*`. – eesiraed Jan 16 '19 at 02:05
2

Is my understanding of the legality of sc = s correct?

Yes, only some detail on the last part needed.

... but any assignment (or reference?) to *s or sc would be illegal.

(I suspect OP means "... or *sc would be illegal.")

Referencing what s or sc points to is OK as in char ch = *sc;

Attempting to change the value of *s or *sc is undefined behavior (UB), not "illegal" as in *sc = 'x';
(See good additional detail by @rici)

With UB, the assignment may work, it might not on Tuesdays, code may crash, etc. It is not defined by C what happens. Certainty code should not attempt it.

chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
  • 1
    `*sc = 'x';` is a constraint violation (6.5.16/2) reagardless of whar `sc` points at. A diagnostic must be produced. `*(char *)sc = 'x';` is UB if whatever `sc` points at was originally defined with a `const` modifier; otherwise it's perfectly legal. (6.7.3/6) (I know you know that. And perhaps the distinction isn't necessary for this question, but it might not hurt.) – rici Jan 16 '19 at 03:59