Deprecated conversion from string const. to wchar_t *

Hello, I have a pump class that requires the use of a member variable, which is a pointer to a wchar_t array containing the port address, that is: "com9".

The problem is that when I initialize this variable in the constructor, my compiler displays a warning with a deprecated conversion.

pump::pump(){ this->portNumber = L"com9";} 

This works fine, but the warning every time I compile is anonymous and makes me feel like I'm doing something wrong.

I tried to create an array and then set a member variable as follows:

 pump::pump(){ wchar_t port[] = L"com9"; this->portNumber = port;} 

But for some reason this makes my portNumber a point in 'F'.

Clearly, another conceptual problem on my part.

Thanks for the help in questions related to noobish.

EDIT:

As a request, the definition of portNumber was:

  class pump { private: wchar_t* portNumber; } 

Thanks to the answers, it is now changed to:

  class pump { private: const wchar_t* portNumber; } 
+4
source share
3 answers

If portNumber is wchar_t* , it must be const wchar_t* .

String literals are immutable, therefore const elements. There is an obsolete conversion from a string literal to a non-constant pointer, but this is dangerous. Make changes to maintain type safety and not use unsafe conversions.

The second error, because you are pointing to the contents of a local variable. When the constructor finishes, the variable leaves, and you point to an invalid location. Using this result leads to undefined behavior.

Finally, use the initialization list:

 pump::pump() : portNumber(L"com9") {} 

Initialization list - initialize, the constructor must complete the construction. (Also, this-> is ugly for almost all C ++ people; it is not good and redundant.)

+11
source

Use const wchar_t* to point to a literal.

The reason the conversion happens is because it was valid from earlier versions of C to assign a string literal to a non const [*] pointer. The reason it is deprecated is because it is not valid for changing a literal, and it is risky to use a pointer that is not a constant to refer to what should not be changed.

[*] C originally did not have const . When const was added, it was obvious that it should apply to string literals, but there was already code written before const that would break if you suddenly had to sprinkle const everywhere. We still pay today for this language violation. Since this is the C ++ you are using, this was not even a change in this language.

+2
source

Apparently portNumber is wchar_t * (not const), right? If yes:

  • the first is incorrect because string literals are read-only (they are constant pointers to an array from char, usually stored in a string table of an executable file that is displayed somewhere in memory, often in a read-only page).
    A char, implicit conversion to non-constant char s / wchar_t was approved by IIRC to ensure compatibility with old code written when const did not even exist; unfortunately, this allowed many morons who don’t know what const correctness means to go away with writing code that sets non-constant pointers, even if constant pointers are the right choice.

  • The second is incorrect, because you make portNumber point to a variable allocated on the stack, which is deleted when the constructor returns. After the constructor returns, the pointer stored in portNumber indicates random garbage.

The correct approach is to declare portNumber as const wchar_t * if it does not need to be changed. If instead it needs to be modified throughout the entire life cycle of the class, usually the best way is to avoid C-style strings and just throw in std::wstring , which will take care of all the books associated with the string.

+1
source

All Articles