http://bugs.winehq.org/show_bug.cgi?id=58465
Bug ID: 58465 Summary: Wide string misbehavior on C++20 mode vs C++17 mode Product: Wine Version: 10.11 Hardware: x86-64 OS: Linux Status: UNCONFIRMED Severity: normal Priority: P2 Component: winelib Assignee: wine-bugs@winehq.org Reporter: messmer.dalton@gmail.com Distribution: ---
Created attachment 78920 --> http://bugs.winehq.org/attachment.cgi?id=78920 Simple Winelib program to demonstate the bug (wine_test.cpp) + build/run script (wine_test.sh) + my test results (output.txt)
When I compile a Winelib application using the `--std=c++20` wineg++ flag instead of `--std=c++17`, I experience unexpected differences in behavior when using `std::wstring`. And in both C++ modes the behavior is incorrect.
For example, when I call the `c_str()` method on `std::wstring` and pass the returned wide C-string to `std::wcslen`, I get different results depending on whether the Winelib application was compiled in C++20 mode vs C++17 mode. And in both cases, the reported string length is incorrect.
Also, the distance between the `begin()` and `end()` iterators is different between C++ modes, and so is the return value of the `length()` method. And all of the results are incorrect in general.
I originally noticed these `std::wstring` problems here: https://github.com/LMMS/lmms/pull/7624#issuecomment-2923573719
I've attached a simple Winelib program that demonstrates the bug to this bug report.
http://bugs.winehq.org/show_bug.cgi?id=58465
Eric Pouech eric.pouech@gmail.com changed:
What |Removed |Added ---------------------------------------------------------------------------- CC| |eric.pouech@gmail.com
--- Comment #1 from Eric Pouech eric.pouech@gmail.com --- This likely stems from the fact that wchar_t is 32 bit on Linux. wineg++ (by default) forces 16bit wchar_t so that a wchar_t is matched with a WCHAR.
But that likely breaks libstd++ (this can be verified by passing -fshort-char to g++ in your repro test, which exhibits the same caveats as the wineg++ ones)
There's no simple solution I'm afraid here.
You may want to keep wchar_t as 32bit for compat with libstd++, and potentially other Linux libraries.
You can pass -fno-short-wchar to wineg++ to let wchar_t be 32bit. That will fix the libstd++ compat issues. But now, you're your on to deal with the wchar_t (32bit) <> WCHAR (16bit) discrepancy in strings std::u16string will be compatible with WCHAR though; but impact on existing codebase (replacing wstring with u16string; 16 <> 32 bit string conversions where required) has to be measured
You can move your app to PE format (where wchar_t will be 16bit, so std::wstring usage will be ok), but will require some more work to call to .so libs if needed