Some puzzles about std :: basic_string on solaris (x86)

Some puzzles about std :: basic_string on solaris (x86)

#include <iostream> #include <string> int main() { const wchar_t* s = L"abcdef"; std::wstring ws(s, s+6); for(int i = 0; i < ws.size(); ++i) { std::cout << ws[i] << std::endl; } return 0; } 

Execution Result:

 97 99 101 0 0 0 

Why not

 97 98 99 100 101 102 

And code

 #include <iostream> #include <string> int main() { const wchar_t* s = L"abcdef"; std::wstring ws; ws.resize(6); for(int i = 0; i < ws.size(); ++i) { std::cout << (ws[i] = s[i]) << std::endl; } return 0; } 

may get the expected result. I am using gcc 3.4.6 , the build command g++ -fshort-wchar stringtest.cpp . Anyone can give expain?

+4
source share
3 answers

The documentation -fshort-wchar reads,

-fshort-wchar

Cancel the base type for wchar_t as short unsigned int instead of the default value for the target. This option is useful for creating programs that run under WINE.

Warning: the -fshort-wchar switch causes GCC to generate code that is not binary compatible with code generated without this switch. Use it to match the binary interface of a non-standard application.

Thus, it seems that this flag causes an observed mismatch, and since the language specification does not speak of such a flag, the behavior can be classified as implementation-defined or undefined.


As a side element, you should use wcout instead of cout when working with wide characters, since wcout designed to handle wide characters:

  • cout - an object of type basic_ostream<char> .
  • wcout - an object of type basic_ostream<wchar_t> .

In this case, the problem is not that you are using values ​​to print, since you are telling the compiler to treat wchar_t as a short unsigned int , anyway.

+5
source

The standard library most likely has not been compiled with --short-wchar . This flag changes the ABI, although it is not detected, as the name change does not change.

+2
source

The ws[i] problem seems to be giving the wrong result; the line seems to contain the expected data when I look at the raw memory. This is rather puzzling why this is happening; as far as I can see, operator[] is just dereferencing a pointer to wchar_t , which works correctly in other places (for example, printing s[i] in your second example). The problem also occurs in later versions of GCC (I tried 4.6.1) and on Linux.

You can get around this using *(ws.begin() + i) instead.

0
source

Source: https://habr.com/ru/post/1381113/


All Articles