There are many times that i get compile errors when I use char* instead of const char*. I am not sure the actual difference, the syntax and the compile mechanism.
+3
A:
If you're after the difference between the two, just think of them as:
- char* is a pointer that points to a location containing a value of type char that can also be changed. The pointer's value can be changed, i.e. the pointer can be modified to point to different locations.
- const char* is a pointer, who's value can be also changed, that points to a location containing a value of type char that cannot be changed.
Rob Wells
2010-07-05 13:14:49
Though what if I allocate memory to both and then assign?
Sunscreen
2010-07-05 13:38:52
@Sunscreen: You'll be able to write to the memory via the `char *` pointer, and not via the `const char *` pointer.
T.J. Crowder
2010-07-05 13:44:02
And then, what is the point of using 'const char*' ?
Sunscreen
2010-07-05 13:47:19
There are several reasons to use `const char *`. One is that it documents that your code will not be modifying the data pointed to. Another is that it will prevent you from inadvertently (e.g. due to a typo like `=` instead of `==` or typing the wrong variable name) writing somewhere you didn't mean to. And it *may* help the compiler determine optimizations that can be made (but probably not if the compiler is already sufficiently smart).
R..
2010-07-05 14:19:55
@Sunscreen: *"And then, what is the point of using 'const char*' ?"* For me, mostly two reasons: 1. As "R." pointed out, it documents your code, it's part of the contract of your function or whatever. 2. Using a `const char *` argument in a function signature when the function doesn't need to modify the string being passed in *may* allow the compiler to do optimizations it otherwise can't do.
T.J. Crowder
2010-07-05 21:34:40
You can't write to the characters in a string literal, no matter how you declare the pointer.
anon
2010-07-05 13:33:26
@Neil: That's true. It would be one of the reasons why trying to would be a really bad idea. :-)
T.J. Crowder
2010-07-05 13:39:32
The thing is I can understand the concept: const int nMyInt = 9;. It is like a #define. Though I cannot grasp the concept for char*.
Sunscreen
2010-07-05 13:44:21
@Sunscreen: A `char ch = 'A';` is a variable (`ch`) with a character you can change. So a `char *` is a *pointer* to a character you can change. In exactly the same way, a `const char ch = 'A';` is a variable (`ch`) for a character you *can't* change, and so a `const char *` is a *pointer* to a character you *can't* change (which usually means it's a pointer to a null-terminated string of them, although that's not necessarily the case).
T.J. Crowder
2010-07-05 14:05:49
@Neil, @Cowder you can't write to string literal for other reason than `const`, as said by you, and this means that indeed in general (from the language point of view) you __can__ write to string literal (e.g. on systems like there we are accustomed to, it's enough to be sure the string is not put in a read-only section)
ShinTakezou
2010-07-05 17:02:38
@shin Both the C and C++ standards say that writing to a literal will result in undefined behaviour.
anon
2010-07-05 17:04:38
@Neil just since they can't force the system running C/C++ programs to a specific memory model (or to use a binary format with certain features)! If I know I can on my system and I disregard portability, then I can do it and it won't be "undefined behaviour" (from the stds point of view, I am writing non perfectly standard code however, of course; I am not saying it is a good practice, I wanted just to specify that it is not intrinsecally impossible)
ShinTakezou
2010-07-05 17:23:35
@shin No matter what you do, from the standard's point of view it will ALWAYS be undefined behaviour. It may of course "work" for your particular implementation.
anon
2010-07-05 17:26:24
@ShinTakezou: To be safe doing that, you're better off with `char foo[] = "My string literal";` which initializes a char array with the *contents* of the string literal. You can then write to the array all you want; you're not writing to the string literal, you're writing to the array.
T.J. Crowder
2010-07-05 17:46:52
@Crowder I know it, but the 'topic' was "writing in a string literal", not in array! thanks anyway
ShinTakezou
2010-07-05 18:30:40
@Neil if I can say that for the system Xyz doing so is ok, it means that for that system Xyz it is __not__ undefined behaviour. The standard has to say that since it can't address all the systems, as already said (and since I've already written it, and the fact that doing so you would not be perfectly standard compliant, what is the new point of your comment?)
ShinTakezou
2010-07-05 18:33:58
@shin You don't understand what is meant by "standard" or "undefined behaviour" - this conversation is now closed from my side.
anon
2010-07-05 18:36:24
@Neil u can't understand english(or my eng),nor logic,nor how faulty's assigning fixed meaning to words that have a general 1.I can't see which part u can't understand,I've already said why std must say,that"feature"is undefined behaviour.-Nobody has forced u to discuss anything anyway,so no reason to specify anything - it looks more like shutting a door theatrically, things that histrions and stupids usually do.
ShinTakezou
2010-07-05 19:59:25
@ShinTakezou: On tone: Let's try not to get into attacks, eh? On the facts: *"if I can say that for the system Xyz doing so is ok, it means that for that system Xyz it is **not** undefined behaviour..."* You can say that **if** the compiler you're using explicitly guarantees it in the documentation, yes. You **can't** say that if you've only demonstrated it empirically (the "works for me" test). You may have just got lucky, or the next minor bugfix version of the compiler might change it, etc., etc. I think that's what Neil was saying, I don't think it was meant to be mean or anything.
T.J. Crowder
2010-07-05 20:40:56
@Crowder I am suceptible, expecially when I am conversing relaxedly only for conversation's sake and someone says I don't understand and "close the conversation" explicitly,when to do so it is enough to not reply at all, so such a comment looks like an arrogant(fine) explanationless(not fine) attack. - It is not up to the compiler. If the system allows to modify literal strings (e.g. since has not a way of making a memory section read-only), there can't exist a single compiler implementation able to force a "segmentation fault". And the standard forces not a compilation-time check.
ShinTakezou
2010-07-05 20:57:37
@ShinTakezou: I should probably step away from this as well, but again, there's a difference between what *works* and what's *defined*. There can be lots of things that work that are still undefined. Writing to memory that should, by the defined standard, not be writeable may *work*. That doesn't make it defined, just functional. It's still undefined behavior barring (again) the non-standard behavior being *documented*, which it could well be for certain classes of system (embedded ones, for instance).
T.J. Crowder
2010-07-05 21:28:49
@Crowder it is why I wrote that it is faulty `assigning fixed meaning to words that have a general 1`.Std can't say differently(or not all compilers on all sys are able to be std-compliant);does the std say «"str literal" _should_ be in RO mem?»Given a specific sys,the behaviour of that std-compliant code is _defined_ (the general meaning).`-std=c99 -pedantic` does not warn,so I interpret such a code as std-compliant.Since I know why I am using it and how it works on my sys,I obtain a defined behaviour,and disregard whatever the std has to say about.Functional in ur terminology.
ShinTakezou
2010-07-06 13:22:08
A:
Probably I'm too picky. In my book, the character(s) pointed to by a const char* can possibly be changed but not via the const char*. A const char * can point to modifiable storage. Example:
char a[] = "abracadabra";
const char * ccp = &a[0]; // ccp points to modifiable storage.
*&a[0] = 'o'; // This writes to a location pointed to by const char* ccp
So, my wording is:
A char * is a pointer that be changed and that also allows writing through it when dereferenced via * or [].
A const char * is a pointer that be changed and that does not allow writing through it when dereferenced via * or [].
Peter G.
2010-07-05 13:33:50
A `const char *` can also simply be cast to a normal `char *` to write to the address. This does NOT mean the write will succeed; for instance the pointer may point to non-writable memory. However, if writing to that address through any other means has well-defined behavior, then removing the const qualifier and writing that way also has well-defined behavior. It's useful for implementing functions like `strstr` which need to be able to handle both `char *` and `const char *` arguments while preserving non-const-ness in the returned pointer.
R..
2010-07-05 14:24:27
Exactly, the same thing also happens the other way around, where a legacy function has uses char* for read-only parameters and you trust it to not modify you (char*)-casted const char * pointers you give it as parameters.
Peter G.
2010-07-05 15:09:42