How to pass "char* a" to "const char*"? [closed] - c++

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
Could you tell me the way to pass the value (char * a) to the value (const char* b)?
For example,
char * str = "Tokyo";
const char *;
"char = str" is OK?

char * str = "Tokyo";
In c++, this is not allowed †. You may not assign a const array (such as a string literal) to a non-const pointer.
const char *;
This is not allowed, because a variable declaration must have a name (unless it's a function argument).
const char *str = non_const_pointer_or_array;
The above is OK in c++.
† Implicit conversion from const to non-const is allowed in c but typically discouraged by compiler warnings. It was deprecated in c++ and not allowed at all since c++11.

In c++, it should just work. Native/Builtin types are automatically convertible to more const, but not to less const.
Therefore:
void foo(const char*) {
}
int main() {
char s[] = {'x', 'y', 'z', '\0'};
foo(s); //Compiles fine.
return 0;
}
This compiles fine, however the other way around, one has to use a const_cast. One should however not lie to the compiler and indicate that something is non const, while in actual fact it is const, as the program behavior in that case is undefined (one cannot know what the behavior of the program might be). const_cast is typically only used when old APIs require char* arguments despite it not modifying the arguments, and should never be used to "lie" to the compiler.
Example:
void some_old_api(char*){}
int main() {
const char* cs = "xyz";
some_old_api(const_cast<char*>(cs));
return 0;
}

A character array hard-coded in your program is a const char*, so you can declare it as const char* str = "Tokyo";Or, when you do have a char* str, you can cast it as follows: const char* myconst = (const char*) str;

Related

Using a const void* with string [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 10 months ago.
Improve this question
In c++11, I have a function that takes a const void* data and a size_t dataSize, so I have to pass to the function the pointer to a string.
function_test( const void* Data, size_t DataSize)
{
std::string received_data((const char*)Data, DataSize);
if (received_data=="1")
{
//do stuff... I need enter here
}
}
I use:
std::string test1 = "1";
function_test(&test1, sizeof(test1));
I expect that received_data is equal to "1" but it's not, why? How can I fix this?
Why test3 is not "1"?
Because std::string is not an array of char. A pointer to std::string is not a pointer to the buffer that std::string class manages where the content of the string is stored. When you reinterpret a pointer to a std::string object as a pointer to char, you get a meaningless representation of the internals of the std::string object.
I need that test3 is equal to "1"
Then use the copy constructor:
std::string test3(test1);
P.S. Don't use C-style casts. Use C++ style static_cast etc. This will make it easier to understand the program that you are writing.
Assuming you need to pass a const void* to a legacy C-style API, you need to use:
std::string test;
reinterpret_cast<const void*>(test.c_str());
C++ is not C.
What you show is close to the following C snippet:
char test1[] = "1";
const void* test2 = test1; // test1 decays to a pointer
char test3[sizeof(test1)];
strcpy(test3, test2);
But a C++ std::string is a complex container with internal data for housekeeping and an array of characters accessible through the data or c_str method:
std::string test1 = "1";
const void* test2 = test1.c_str();
std::string test3(static_cast<const char*>(test2), sizeof(test1));

C++ adding chars to a pointer [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 years ago.
Improve this question
From my understanding a string is just an array of char, so if i have a pointer reference to some char values shouldn't I be able to do:
*dest = "char"
However that doesn't work i have to do:
*dest = 'c';
*dest = 'h';
*dest = 'a';
*dest = 'r';
so if i have a pointer reference to some char values shouldn't I be able to do:
*dest = "char"
No, you shouldn't be able to do so.
*dest is a char. A single char object can only hold a single char object. A string is an array of characters. You cannot assign a string to a char.
However, if you had a pointer reference to some const char values, then you could assign the pointer like this:
dest = "char"
This would make the referred pointer to point to the string literal. However, this is different from *dest = 'c'; *dest = 'h'; .... The pointer assignment modifies the pointer and keeps the previously pointed characters unmodified, while assigning to the pointed character modifies the pointed characters, while keeping the pointer unmodified.
I'm guessing that by 'string' you ment a C-style string, so a char*
*dest = "char"
From what you said, dest is a char&*, when you dereference it, you get a char, type of "char" is const char*, so you're trying to assign a const char* to a char, which is a compile time error.
You should use std::string, which will enable you to do the assignment you described above, and also allocate and free memeory for you.
std::string dest = "char";

Why string literals are allowed to be assigned to pointer of type char * in C++ [duplicate]

This question already has answers here:
how is char * to string literal valid?
(5 answers)
Closed 5 years ago.
Using visual studio, I declared a pointer of type char * and assigned to it a string literal. I then hovered the mouse over the string literal and it displayed its type: (const char [4])"abc".
How is this allowed? it compiles without warnings or errors, whilst assigning to the pointer an array of type const char [] fails, for obvious reasons, with an error message:
a value of type "const char *" cannot be assigned to an entity of type "char *"
So, why is it allowed for string literals?
int main(void)
{
char *p = "abc"; // no error here
const char str[] = "abc";
//p = str; This line generates an error
return 0;
}
EDIT: answer updated to incorporate info from Story Teller's comment.
In the olden days, const didn't exist, and people wrote things like char* p = "abc" all the time. As long as the didn't then do something like p[0] = 'z', their program worked. To remain compatible with such code, some compilers allow string literals to be assigned to non-const pointers if you don't ask the compiler to be super-strict. If you take advantage of this feature, you still should not ACTUALLY modify the string.

warning: deprecated conversion from string constant to 'char*'' [duplicate]

This question already has an answer here:
C++ warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
(1 answer)
Closed 8 years ago.
I have declared the string array in my code as follows.
char *arr[] ={
"xyz",
"abc",
"pqr",
NULL
};
When compile then got following warning
warning: deprecated conversion from string constant to 'char*''
i know that "xyz" and other string literal are const char and my array is char* so have resolve it by declaring my array const char* arr but i loss the control to point this array in another pointer.
So to resolve above issue have declared array as follows
char *arr[] ={
(char *)"xyz",
(char *)"abc",
(char *)"pqr",
NULL
};
But this type of declaration not fair when need large array (more then 100 string array).
So any one have idea to resolve it by another way.
You don't lose any re-pointing options by making the array a const char* arr[]. Note that there's a huge difference between const char * p (a mutable pointer to an immutable char) and a char * const p (an immutable pointer to a mutable char). This code is perfectly valid:
const char *arr[] = {
"xyz",
"abc",
"pqr",
NULL
};
arr[1] = "ghi";
Live example
There is a difference between a const char* and char *const if your pointer is a const char* you can still point it to another location but you cannot modify the elements it contains. The correct solution in this case is to make the array const char*.
String literals are constant, so you need const pointers to refer to them:
const char *arr[] = {
// whatever
};
Historically, it used to be possible (but dangerous) to convert string literals to non-const char*, for compatibility with ancient code that didn't know about const. This conversion has been deprecated for many years, and finally removed from the language in 2011.

C++ deprecated conversion from string constant to 'char*'

I have a class with a private char str[256];
and for it I have an explicit constructor:
explicit myClass(char *func)
{
strcpy(str,func);
}
I call it as:
myClass obj("example");
When I compile this I get the following warning:
deprecated conversion from string constant to 'char*'
Why is this happening?
This is an error message you see whenever you have a situation like the following:
char* pointer_to_nonconst = "string literal";
Why? Well, C and C++ differ in the type of the string literal. In C the type is array of char and in C++ it is constant array of char. In any case, you are not allowed to change the characters of the string literal, so the const in C++ is not really a restriction but more of a type safety thing. A conversion from const char* to char* is generally not possible without an explicit cast for safety reasons. But for backwards compatibility with C the language C++ still allows assigning a string literal to a char* and gives you a warning about this conversion being deprecated.
So, somewhere you are missing one or more consts in your program for const correctness. But the code you showed to us is not the problem as it does not do this kind of deprecated conversion. The warning must have come from some other place.
The warning:
deprecated conversion from string constant to 'char*'
is given because you are doing somewhere (not in the code you posted) something like:
void foo(char* str);
foo("hello");
The problem is that you are trying to convert a string literal (with type const char[]) to char*.
You can convert a const char[] to const char* because the array decays to the pointer, but what you are doing is making a mutable a constant.
This conversion is probably allowed for C compatibility and just gives you the warning mentioned.
As answer no. 2 by fnieto - Fernando Nieto clearly and correctly describes that this warning is given because somewhere in your code you are doing (not in the code you posted) something like:
void foo(char* str);
foo("hello");
However, if you want to keep your code warning-free as well then just make respective change in your code:
void foo(char* str);
foo((char *)"hello");
That is, simply cast the string constant to (char *).
There are 3 solutions:
Solution 1:
const char *x = "foo bar";
Solution 2:
char *x = (char *)"foo bar";
Solution 3:
char* x = (char*) malloc(strlen("foo bar")+1); // +1 for the terminator
strcpy(x,"foo bar");
Arrays also can be used instead of pointers because an array is already a constant pointer.
Update: See the comments for security concerns regarding solution 3.
A reason for this problem (which is even harder to detect than the issue with char* str = "some string" - which others have explained) is when you are using constexpr.
constexpr char* str = "some string";
It seems that it would behave similar to const char* str, and so would not cause a warning, as it occurs before char*, but it instead behaves as char* const str.
Details
Constant pointer, and pointer to a constant. The difference between const char* str, and char* const str can be explained as follows.
const char* str : Declare str to be a pointer to a const char. This means that the data to which this pointer is pointing to it constant. The pointer can be modified, but any attempt to modify the data would throw a compilation error.
str++ ; : VALID. We are modifying the pointer, and not the data being pointed to.
*str = 'a'; : INVALID. We are trying to modify the data being pointed to.
char* const str : Declare str to be a const pointer to char. This means that point is now constant, but the data being pointed too is not. The pointer cannot be modified but we can modify the data using the pointer.
str++ ; : INVALID. We are trying to modify the pointer variable, which is a constant.
*str = 'a'; : VALID. We are trying to modify the data being pointed to. In our case this will not cause a compilation error, but will cause a runtime error, as the string will most probably will go into a read only section of the compiled binary. This statement would make sense if we had dynamically allocated memory, eg. char* const str = new char[5];.
const char* const str : Declare str to be a const pointer to a const char. In this case we can neither modify the pointer, nor the data being pointed to.
str++ ; : INVALID. We are trying to modify the pointer variable, which is a constant.
*str = 'a'; : INVALID. We are trying to modify the data pointed by this pointer, which is also constant.
In my case the issue was that I was expecting constexpr char* str to behave as const char* str, and not char* const str, since visually it seems closer to the former.
Also, the warning generated for constexpr char* str = "some string" is slightly different from char* str = "some string".
Compiler warning for constexpr char* str = "some string": ISO C++11 does not allow conversion from string literal to 'char *const'
Compiler warning for char* str = "some string": ISO C++11 does not allow conversion from string literal to 'char *'.
Tip
You can use C gibberish ↔ English converter to convert C declarations to easily understandable English statements, and vice versa. This is a C only tool, and thus wont support things (like constexpr) which are exclusive to C++.
In fact a string constant literal is neither a const char * nor a char* but a char[]. Its quite strange but written down in the c++ specifications; If you modify it the behavior is undefined because the compiler may store it in the code segment.
Maybe you can try this:
void foo(const char* str)
{
// Do something
}
foo("Hello")
It works for me
I solve this problem by adding this macro in the beginning of the code, somewhere. Or add it in <iostream>, hehe.
#define C_TEXT( text ) ((char*)std::string( text ).c_str())
I also got the same problem. And what I simple did is just adding const char* instead of char*. And the problem solved. As others have mentioned above it is a compatible error. C treats strings as char arrays while C++ treat them as const char arrays.
For what its worth, I find this simple wrapper class to be helpful for converting C++ strings to char *:
class StringWrapper {
std::vector<char> vec;
public:
StringWrapper(const std::string &str) : vec(str.begin(), str.end()) {
}
char *getChars() {
return &vec[0];
}
};
The following illustrates the solution, assign your string to a variable pointer to a constant array of char (a string is a constant pointer to a constant array of char - plus length info):
#include <iostream>
void Swap(const char * & left, const char * & right) {
const char *const temp = left;
left = right;
right = temp;
}
int main() {
const char * x = "Hello"; // These works because you are making a variable
const char * y = "World"; // pointer to a constant string
std::cout << "x = " << x << ", y = " << y << '\n';
Swap(x, y);
std::cout << "x = " << x << ", y = " << y << '\n';
}