C2440: '=': cannot convert from 'const char [9]' to 'char*' - c++

I am working on a Qt5 project written in C++. Building the project gives an error:
C2440: '=': cannot convert from 'const char [9]' to 'char*'
Which points to the line of code below:
port_name= "\\\\.\\COM4";//COM4-macine, COM4-11 Office
SerialPort arduino(port_name);
if (arduino.isConnected())
qDebug()<< "ardunio connection established" << endl;
else
qDebug()<< "ERROR in ardunio connection, check port name";
//the following codes are omitted ....
What is the problem here, and how can I correct it?

In C++, in contrast to C, string literals are const. So any pointer to such a string literal must be const, too:
const char* port_name = "\\\\.\\COM4"; // OK
// char* port_name = "\\\\.\\COM4"; // Not OK

String literals are constant data in C++ (compilers tend to store them in read-only memory when possible).
In C++11 and later, you can no longer assign a string literal directly to a pointer-to-non-const-char (char*) 1.
1: though some C++11 compilers may allow it as a non-standard extension for backwards compatibility, which may need to be enabled manually via compiler flag.
So, you need to declare port_name as a pointer-to-const-char instead (const char * or char const *). But then you will have to cast it back to a non-const char* when passing it to SerialPort():
const char *port_name = "\\\\.\\COM4";
SerialPort arduino(const_cast<char*>(port_name));
Or simply:
SerialPort arduino(const_cast<char*>("\\\\.\\COM4"));
The alternative is to declare port_name as a non-const char[] buffer, copy the string literal into it, and then pass it to SerialPort():
char port_name[] = "\\\\.\\COM4";
SerialPort arduino(port_name);

Related

Arduino, understanding invalid conversion warning char*

what is the problem in arduino
C:\Users\swartwq\Desktop\zx\sketch_jun06e\sketch_jun06e.ino:12:33: warning: ISO C++ forbids converting a string constant to 'char*' [-Wwrite-strings]
In C++
char* a = "a"; //invalid
const char* b = "b"; // valid
char c[] = "c"; //valid
The reason why the first line is invalid is that a is a pointer to static read-only data and therefore is wrong to be non-const. C on the other hand is ok because the string "c" is allocated immediately on the stack and can therefore be changed.

Cannot construct CString from a char

In VS2008, I try to construct a CString from a char, as follows:
CString str = CString(_T('A') + 5);
But will get the following compile error:
error C2440: '' : cannot convert from 'int' to 'CString'
I belive TCHAR and int is exchangable in C++, so why it refuses to accept the TCHAR type parameter to construct a CString?
The purpose of the line is to construct a CString with only one character _T('F'). Not to get "A5".
I try to understand how the compiler processes the code, as follows:
It will first promote _T('A') to an integer.
It will add the integer value of _T('A') by 5.
It will get a new integer and cannot find a way to convert it back to TCHAR, which can be used as input parameter for CString constructor.
The CstringT constructors that accept a char or a wchar_t are explicit. See the docs.
The explicit specifier in C++ means that the compiler is not allowed to do an implicit conversion of the parameter(s). See also explicit specifier.
Thus the compiler cannot (is not allowed to) implicitly convert the int value to char or wchar_t.
(Note that this depends on the flag _ATL_CSTRING_EXPLICIT_CONSTRUCTORS being set. Without the flag being set, the constructors are not explicit, but then it's ambiguous which constructor to chose.)
So you need to explicitly cast the parameter to char or wchar_t, depending on what you want:
CStringA str = CStringA(static_cast<char>('A' + 5));
or:
CStringW str = CStringW(static_cast<wchar_t>(L'A' + 5));
CString will not implicitly convert an int to CString. However you can try like so
CString str;
char c = 'A';
int i = 5;
str.Format(L"%c%d",c, i); // unicode assumed

Argument of type "unsigned char *" is incompatible with parameter of type "const char *"

I was using the Decoder for Microsoft Script Encoder. It works perfectly well when I run it in Codeblocks. But when I run it in Visual Studio, it shows me the following errors
Snippet 1:
char decodeMnemonic(unsigned char *mnemonic)
{
int i = 0;
while (entities[i].entity != NULL)
{
**if (strcmp(entities[i].entity, mnemonic) == 0)**
**//Error 1: cannot convert argument 2 from 'unsigned char *'
// to 'const char *'**
return entities[i].mappedchar;
i++;
}
printf("Warning: did not recognize HTML entity '%s'\n", mnemonic);
return '?';
}
I had to integrate the Decoder in a program, so instead of passing the filenames as command line arguments, I have given their filepaths myself in the code.
Snippet 2:
int main()
{
unsigned char *inname = "C:\\Users\\Karthi\\Desktop\\Project Winter 2018-19\\poweliks_sample\\poweliks_encoded_js.bin";
unsigned char *outname = "C:\\Users\\Karthi\\Desktop\\Project Winter 2018-19\\poweliks_sample\\decoded1.txt";
unsigned int cp = 0;
//**Error 2: 'initializing': cannot convert from 'const char [87]' to 'unsigned char *'**
You can use reinterpret_cast (for unsigned char* to const char*). But if you go from const unsigned char* to a non const type, you have to use const_cast first, since reinterpret_cast cannot cast away a const.
The paragraph below gives a brief overview, why your code did not work.
According to C99 Standard (similiar to other C standards), a string literal has static storage duration and its type is char[] The standard says:
If the program attempts to modify such an array, the behavior is undefined.
The reason why your program worked, when you used argv is, that argv is not considered as an array of string literals. This means you can modify them.
Here are the solutions for your problems:
Snippet 1:
strcmp is a method to compare two C Strings. It expects const char* types.
int strcmp ( const char * str1, const char * str2 );
You have two option to solve it:
Declare your method like this
char decodeMnemonic(const char *mnemonic)
Use C++Strings and declare your method like this
char decodeMnemonic(std::string mnemonic)
If you use the second solutions you have to call the c_str()-Method to use it in strcmp
if (strcmp(entities[i].entity, mnemonic.c_str()) == 0)
Or you use only C++-String: read here how to use it: http://www.cplusplus.com/reference/string/string/compare/
Snippet 2: You can't use it like this because you have string literals which are arrays constant characters.
Please use C++-Strings. You work with C++, so use his features (https://www.geeksforgeeks.org/stdstring-class-in-c/)
Anyway if you want to use it C-like: https://www.programiz.com/c-programming/c-strings
char c[] = "abcd";
char c[50] = "abcd";
Or with const (C++)
char *str1 = "string Literal";
const char *str2 = "string Literal";

invalid conversion from const char * to char * in Linux with Ternary Operator

Example 1:
char* message = ( m_message != NULL ? m_message : "" );
above line gives compiler error as invalid conversion from const char* to char*. in g++ compiler. but the below piece of code works.
Example 2:
char* message;
if(m_message)
message = m_message;
else
message = "";
Why do I get a compiler error with g++ in the first example but not the second? Both ways work fine in Windows.
The string literal -> char* conversion is allowed (but deprecated) only if it is direct - you can't let the value "pass through" somewhere else to decay into a const char*.
Your second code is a conversion directly from a string literal to a char*, which is "only" deprecated.
The first one is first a pointer decay to const char* - the result of m_message != NULL ? m_message : "" is a const char* - and then an attempt to convert the resulting const char* to a char*, which isn't allowed.
This code also produces an error, for the same reason:
const char* empty() { return ""; }
char* message;
if(m_message)
message = m_message;
else
message = empty();
The type of string literal in C++ is not "char *", but "const char[n]", i.e. array of const characters (in this case const char[1]). The conversion to char * was initially allowed for backward compatibility with C library calls, but now it is deprecated, because it is not safe.
I get "-Werror=write-strings" in both cases with g++.

cannot convert from 'const char [3]' to 'char *' x100000 (Qt Creator C++ Windows 32)

Everything was working fine just five minutes ago when I tapped f5 and got 102 errors:
error: C2440: 'initializing' : cannot convert from 'const char [17]' to 'char *'
Conversion from string literal loses const qualifier (see /Zc:strictStrings)
That specific one is at line 30:
char* hexchars = "0123456789ABCDEF";
I haven't touched the file the errors are in for at least a week. I'd normally say I accidentally changed something in the compile args or something, but I haven't opened settings since much before it started erroring.
Any ideas? I must have absentmindedly changed some setting but I really can't remember thinking "uh oh what did I just do?"
When you use code like this
char *astring2 = "some letters";
C++ (and C) puts that into read only memory. You can not modify the contents of a char pointer initialized with a literal even if it is not const.
Also you can not change the address of the pointer because it will cause a memory leak due to the rule above.
This, however, does not follow that rule UNLESS you make it const:
char astring[] = "some letters that can be changed";
char *ptrToString = astring; //work
astring2 = astring //not work
String literals are of type char const[N] since C++ was first standardized. At this point C didn't support const and a lot of code assigned string literals to char*. As a result a special rule was present in C++ which allowed initialization of char* from string literals. This rule was immediately deprecated.
C99 introduced a const keyword, too. When C++11 was standardized the deprecated rules was pulled and it is no illegal to initialize a char* from a string literal as it should have been right from the stand. The expectation was that C++ compilers warned about the deprecated assignment since years (and all vendors stated they did), i.e., users had years of lead-time to fix their code.
The obvious fix is to initialize a char const* instead of a char* from a string literal.
If you really need a pointer to a mutable array of chars you can create it and get it initialized using
char array[] = "string literal";