I’ve got a function which receives a char * argument:
Foo::Foo (char * arg0) {
....
}
In the original example, a char[] is used to pass this value…
char bar[] = "Bar";
Instance.foo (bar);
…which works fine.
But, I’ve found that I can pass a string literal, cast as a char *, without any warnings from the compiler.
Instance.Foo ((char *) "Bar");
However, from my reading, it seems that should be avoided – the value of the memory that is pointed to could change.
Is the above statement true (“this should be avoided”) or is this appropriate in this situation?
Edit – further research turned up this article which addresses my question pretty well…
Yes, avoid that. Now, if your function took a
const char *there is nothing wrong with calling it with a string literal.C++ compilers support string-literal to
char *for backwards compatibility reasons only, and writing to a string literal results in undefined behavior.When you do
char bar[] = "Bar";you are doing something fundamentally different (namely initializing an array of 4 characters with the values{'B', 'a', 'r', '\0'}that you are free to modify) than when you dochar bar* = "Bar";(where you are creating a non-constpointer to a 4 byte string that you may not modify).In my opinion, you should never turn a string literal directly into a
char*, instead put it into aconst char*then (if you are communicating with a legacy API) explicitlyconst_cast<char*>theconstness away, with a comment saying you are talking to a legacy API that has guarantees not to change thechars. The advantage of this is you can search your program for thoseconst_casts when the API is upgraded, or you want to find where the segmentation fault involving writing to achar*came from.One could even wrap the legacy API with
const char*versions that do theconst_castwithin them.The absolute worst situation would be having a bunch of
char*s hanging around, some of them writable, others from string literals.