Hi, I’m trying to compile an old C++ code on macOS that relies on having -fshort-wchar, so the code assumes sizeof(wchar_t) == 2 bytes.
The problem is that external libc++.dylib was not compiled with -fshort-wchar, so everything in this library still expects sizeof(wchar_t) to be 4 bytes. So, any usage of std::wstring (or anything else that somehow uses wchar_t) from a project compiled with -fshort-wchar ends up in making a lot of undefined behaviors, including out of bounds memory writes, and crashes.
Is there an option to somehow convince clang to link a short-wchar-enabled libc++ to my project? What I would need to do in order to make it happen? From what I was thinking, I would need to:
Why don’t you use std::u16string? Then you have a fixed-size character across platforms. Otherwise, the process you described is almost exactly what you have to do. It would probably also be a good idea to either
define _LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS and compile with -fvisibility=hidden, or
set LIBCXX_ABI_NAMESPACE to something different like __short_wchar
to avoid dynamically linking against the wrong symbol.
(BTW if you decide to link statically you can also look into enabling the unstable ABI)
Great that it works! You actually don’t have to pass -fvisibility=hidden -D_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS=ON to the build command. You’d have to pass the flags when building your application if you don’t change the ABI namespace while compiling libc++. (i.e. you don’t have to pass it at all). Also, if you want some performance for free, you can add -DLIBCXX_ABI_UNSTABLE=On when building libc++. You have to build everything that uses libc++ from source, but that shouldn’t be a problem, since you seem to already do that.
That’s a good point. I haven’t encountered any problems probably because my project also uses -nostdlib. Lots of libc functions are reimplemented (like wcslen that expects 2-byte wchar_t). But without -nostdlib it probably wouldn’t work indeed.