0

I know this may seem like a stupid question, but I am really having trouble understanding some particular examples of C code that involve a declaration of type const char *.

The example that got me thinking about it is in the answer at Parsing csv with c. In particular, the function defined as:

const char* getfield(char* line, int num) { const char* tok; for (tok = strtok(line, ";"); tok && *tok; tok = strtok(NULL, ";\n")) { if (!--num) return tok; } return NULL; } 

My understanding of const char * declarations is that it defines a mutable pointer to an immutable array of characters. This array is assigned in the data section at compile time. However in this case (and many other code examples), the const char * declaration is not for a string literal. How can this memory be assigned for this at compile time if the actual value of the string is not known until the function executes?

5
  • 1
    There is an example in the standard "const float *" is not a qualified type — its type is "pointer to const-qualified float" and is a pointer to a qualified type (6.2.5, 32). You promise that you will not modify what tok points to, and if you do, it undefined behavior. Commented Dec 11, 2022 at 2:16
  • @AllanWind I think a standard would be super helpful. Is this the ANSI C standard, or K&R, or something else? Commented Dec 11, 2022 at 2:30
  • The last working draft of ISO/IEC9899:2017 is freely available. Commented Dec 11, 2022 at 2:32
  • 1
    const char T* declares a pointer to an object (which might be the first object in an array of such objects) which you promise you won't try to modify. The compiler will probably help you keep that promise by producing warning or error messages if it detects that you are trying to modify an object through that pointer, but it can't actually know in all cases. However, it is allowed to optimise, assuming that you will play by the rules. If you read a value from that pointer twice, the compiler might eliminate the second read and assume that the first value is still valid. Commented Dec 11, 2022 at 2:32
  • 1
    Anyway, if you will not using a pointer to modify a value, it makes sense to declare it as a pointer to const. The compiler is likely to produce useful error messages (since modifying a value you didn't plan to modify is almost certainly an error). It might even warn you about passing the pointer as an argument to a function which might try to modify the value pointed to. So it can help. But it doesn't guarantee that the memory being pointed at is read-only. Commented Dec 11, 2022 at 2:37

1 Answer 1

2

this

const char* tok; 

creates a pointer on the stack. It has an undefined value, it points nowhere

this

for (tok = strtok(line, ";"); 

then makes it point to somewhere in line (depends on contents)

your comments

My understanding of const char * declarations is that it defines a mutable pointer to an immutable array of characters. This array is assigned in the data section at compile time.

First sentence, almost, it creates a pointer that might point to an immutable array of chars. Like this

 const char * msg = "hello world"; 

But is can also point nowhere

 const char * msg = NULL; 

Or to a mutable array of characters

 char msg[] = "HelloWorld"; // mutable const char *msgconst = msg; 

the second sentence

This array is assigned in the data section at compile time

Yes, if this is a literal. Ie like this example again

 const char*msg = "Hello World"; 

but the msgconst assignment is not like that, the characters are on the stack

Hope this helps

EDIT

The pointer points where it is told to do, making it const or not has zero effect on where the data is. The data is where it is.(!). You need to think about where the data is created, nothing to do with the pointer, the pointer can point at a literal, stack data, static data (mutable in data segment), heap.

Why use const

  • if the string is immutable then the pointer must be const. C allows you to assign a literal to a non const pointer for historical reasons, c++ does not

  • You want to make it clear that this string should not be changed. In your code case you really should not mess with the string strtok is processing. Although it returns char* , this is good practice

  • functions like strlen that do not change the string passed to them declare their arguments as const char*, its part of their contract: we dont change the string

But having the word const does not change anything about storage, and does not save any space anywhere

Sign up to request clarification or add additional context in comments.

6 Comments

This is very helpful. So the array that it points to is not always assigned to the data section, but only when it is a string literal. I guess the only other question I have is what is the benefit of using "const char *" instead of just "char *" here? I assumed the benefit is usually that it saves precious space on the stack, but in this case the characters will get put there anyway. What benefit does "const" give?
@Luke see edits
Thanks for the reply, although I am slightly more confused now. As you mentioned in your edits, the const char * pointer can point to a mutable array. So now I am even more curious as to what the benefit of it is as opposed to just declaring char * without the "const". Sorry if these are trivial questions, as you can tell I am a complete beginner.
If a function argument is const-qualified then caller can assume that the value is not changed, otherwise caller would have copy before passing it in the value.
@AllanWind thank you, that makes a lot of sense. And thanks for the standard, I will go take a look.
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.