I am trying to create a TCHAR* variable by using
TCHAR* example = TEXT("example");
but it wont even compile and says: A value of type const wchar_t* cannot be used to initialize an entity of type TCHAR*.
What should I do?
You have to add const, because the TEXT() macro returns a pointer to a const wchar_t.
const TCHAR* example = TEXT("example");
If the assignment were allowed without the const, you would be able to modify the const wchar_t data through the pointer.
See also A value of type "const char*" cannot be used to initialize an entity of type "char *"
Related
I have written a typedef like the following:
typedef wchar_t *cString;
and I put the const keyword independently as follow:
void func(const cString)
But when passing wstring::c_str() to the previous method func(wstring::c_str()), it tells me there's an error argument of type "const wchar_t *" is incompatible with parameter of type "cString", although the type cString is wchar_t * with an independent const.
and to resolve that problem I must either define the typedef as typedef const wchar_t *cString; or use const wchar_t* directly without typedef.
Why that problem occurred?
typedef wchar_t *cString; declares cString as a mutable pointer to mutable data.
const cString declares a const one of these, which is therefore a const pointer to mutable data. The matching typedef for this would be typedef wchar_t(*const cString);, I think. (One wouldn't normally typedef a const pointer like this, so I'm not 100% certain on the syntax)
However, wstring::c_str() returns a mutable pointer to const data. The matching typedef for this would be typedef (const wchar_t) *cString;, with or without parenthesis.
Therefore func(wstring::c_str()) is passing a (mutable) pointer to const data, to a function that expects a (const) pointer to mutable data. The pointer itself can be converted from mutable to const, but the data it points to can't be silently converted from const to mutable, so it tells you something is wrong.
Your argument is of type const wchar_t * (a.k.a. wchar_t const *).
Your parameter is of type wchar_t * const (the "independent const" goes last).
There is a difference.
I am expecting my function to work just the same as the function "strchr" I am using from the cstring / string.h library.
I understand that I cannot cast a " const char* " variable / array to " char* ". Yet, how is the predefined "strchr" function able to be passed both "const char" and "char" data type arrays and work just fine ? How could I change mine so that it works, too ?
char* my_strchr(char *place_to_find, char what_to_find)
{
for(int i=0;place_to_find[i];i++)
if(what_to_find==place_to_find[i]) return place_to_find+i;
return NULL;
}
...
int main()
{
const char vocals1[]="AEIOUaeiou";
char vocals2[]="AEIOUaeiou";
cout<<strchr(vocals1,'e');
cout<<strchr(vocals2,'e');
cout<<my_strchr(vocals1,'e');
cout<<my_strchr(vocals2,'e');
return 0;
}
As you could probably already tell, my third cout<< does not work.
I am looking for a way to change my function ( I am guessing the first parameter should somehow be typecast ).
How can I make my strchr function take both 'const char' and 'char' arrays as first parameter?
You could change the argument to be const char*. That would allow passing both pointers to char as well as const char.
However, you return a non-const pointer to that array, which you shouldn't do if the pointer is to a const array. So, when passing a const char*, your function should also return const char*
Yet, how is the predefined "strchr" function able to be passed both "const char" and "char" data type arrays and work just fine ?
There are two predefined std::strchr functions. One that accepts and returns char* and another that accepts and returns const char*:
const char* strchr(const char* str, int ch);
char* strchr( char* str, int ch);
If you would wish to return char* in case of char* argument, you need to have a different function for each case, like the standard library has. You can use an overload like the standard library does, or you can use a function template to generate both variations without repetition:
template<class Char>
Char* my_strchr(Char *place_to_find, char what_to_find)
Note that the C version of the function is declared char *strchr(const char *str, int ch). This makes the single function usable in both cases, but is unsafe, since the type system won't be able to prevent the user of the function from modifying though the returned non-const pointer even when a const array was passed as an argument.
Make two overloads, the way it is done in the C++ standard library:
char* my_strchr( char *place_to_find, char what_to_find)
const char* my_strchr(const char *place_to_find, char what_to_find)
Even though in your case only the second overload would be sufficient (demo) you would not be able to support an important use case, when you need to find a character and then replace it:
// This would not work with only one overload:
char *ptr = my_strchr(vocals2,'e');
if (ptr) {
*ptr = 'E';
}
That is why the non-const overload is necessary.
Note: I assume that you are doing this as a learning exercise, because C-style string functions are no longer necessary for new development, having been replaced with std::string functionality.
Short answer: make the type of the place_to_find const char*
The reason for your error is that you cannot implicitly convert a pointer to a const char to a pointer to a non-const char. If you could, then you could change the char that the pointer points to and it would defeat the purpose of having it a const char type in the first place.
You can implicitly convert a pointer to a non-const char to a pointer to a const char because it does not remove any restrictions.
L.E.: Also, the return value should be a const char*, because again, if you don't, it would remove the const restriction which is not allowed. The only problem with that is that you would not be able to modify the array through the pointer returned. If you also want that, then you would have to overload the method on both char and const char.
I need to make and WCHAR.
But it wont work, and i always get an error:
Error C2440 'initializing': cannot convert from 'const wchar_t [11]' to 'WCHAR *'
StateError (active) E0144 a value of type "const wchar_t *" cannot be used to initialize an entity of type "WCHAR *
My code:
WCHAR *Testlooll = L"TEST";
L"TEST" is a string literal of type const wchar_t[5], which is an array of const characters (since the literal exists in read-only memory). You are trying to initialize a WCHAR*, which is a pointer to a non-const character, to point at that array.
Initializing a pointer to non-const character data to point at an array of const character data is deprecated in C++98 (to maintain backwards compatibility with legacy code), and is illegal in C++11 onwards.
You need to change the declaration of Testlooll according:
const WCHAR *Testlooll = L"TEST";
Or:
LPCWSTR Testlooll = L"TEST";
In addition to Remy Lebeau's answer, if for some reason you can't modify the defination of Testlooll. You can just cast the const arry to a wchar_t*. For example,
struct someLibaryType
{
WCHAR *Testlooll
};
someLibaryType a;
a.Testlooll = (wchar_t*)L"TEST";
Someone maybe argue should cast to WCHAR* just keep same with the defination type of Testlooll. But in this context, you've already used L to identify a string, so it has to be wchar_t*.
Given this code:
void group::build(int size, std::string *ips){
/*Build the LL after receiving the
member list from bootstrap*/
head = new member("head");
member *temp1,*temp2;
temp1 = new member(ips[0].data()); // error here
// ....
}
member::member(char *ip){
strcpy_s(this->ip_addr,sizeof(ip),ip);
this->next = NULL;
this->previous = NULL;
}
And a pointer to string defined as:
std::string *ips;
I want to initialize the array, ips with strings but when I try to get the char data from any array member I get the error:
cannot convert parameter from const char * to char *
Why?
The function you are calling expects a pointer to a modifiable buffer, char*. You are passing a pointer to a non-modifiable buffer, const char*.
Since your member function does not modify its input you should change its declaration to receive const char*.
member::member(const char *ip)
Change line
member::member(char *ip)
to
member::member(const char *ip)
and, i'm not sure about your usage of strcpy_s
Well, data() returns a const char*, hence the error. You should change member::member to receive a const char*, as you're copying its value anyway.
Also, note that sizeof(ip) is equal to sizeof(char*), which is just a size of a pointer. You should pass the size of the this->ip_addr buffer instead.
Because member::member is defined to take char * as a parameter, and string.data() is giving a const char * as a value (since it is returning a reference to its own internal memory). You could use const_cast or change member::member method signature.
Change this:
member::member(char *ip)
to this
member::member(const char *ip)
That is, you've to change the parameter type of the constructor.
Alternatively, which is also a better solution, simply make the parameter const std::string &:
member::member(const std::string &)
This approach lets use better interfaces provided by std::string class. These interfaces are much more better than C-string interfaces such as strcpy, strlen, strcat etc.
std::string data has this signature
const char* data() const;
You are trying to call the member c'tor with which expects char * so here is your error.
Change this : member::member(char *ip)
To this : member::member(const char *ip)
I've got a function that requires const some_type** as an argument (some_type is a struct, and the function needs a pointer to an array of this type). I declared a local variable of type some_type*, and initialized it. Then I call the function as f(&some_array), and the compiler (gcc) says:
error: invalid conversion from ‘some_type**’ to ‘const some_type**’
What's the problem here? Why can't I convert a variable to const?
See: Why can't I pass a char ** to a function which expects a const char **? from the comp.lang.c FAQ.
You have a few options to get around what jamesdlin outlined in his answer.
You could use an intermediate variable.
some_type const* const_some_array = some_array;
f(&const_some_array);
You could change the parameters of f.
void f(some_type const* const* some_array);
You probably need to specify some more context, for instance is the argument passed data into or out of (or both?) the function?
Try making your variable const as well:
some_type const *some_array = ....;
This reads as "some_array is a pointer to a const some_type". The code can't modify the thing being pointed at. So you have to declare your variable const before passing it to the function.
(Edited...)