Qt、MSVC 和/Zc:wchar_t- == 我想炸毁世界

2021-12-09 00:00:00 qt internationalization c++ boost

所以 Qt 在 windows 上是用/Zc:wchar_t- 编译的.这意味着 wchar_t 不是某些内部类型(我认为是 __wchar_t)的 typedef,而是 unsigned short 的 typedef.真正酷的是 MSVC 的默认值是相反的,这当然意味着您使用的库很可能是用 wchar_t 编译的,而 wchar_t 与 Qt 的 wchar_t.

So Qt is compiled with /Zc:wchar_t- on windows. What this means is that instead of wchar_t being a typedef for some internal type (__wchar_t I think) it becomes a typedef for unsigned short. The really cool thing about this is that the default for MSVC is the opposite, which of course means that the libraries you're using are likely compiled with wchar_t being a different type than Qt's wchar_t.

这当然不会成为问题,除非您尝试在代码中使用诸如 std::wstring 之类的东西;特别是当一个或多个库具有接受它作为参数的函数时.实际发生的情况是,您的代码可以愉快地编译但随后无法链接,因为它正在使用 std::wstring<unsigned short...> 查找定义,但它们只包含需要 std 的定义::wstring<__wchar_t...>(或其他).

This doesn't become an issue of course until you try to use something like std::wstring in your code; especially when one or more libraries have functions that accept it as parameters. What effectively happens is that your code happily compiles but then fails to link because it's looking for definitions using std::wstring<unsigned short...> but they only contain definitions expecting std::wstring<__wchar_t...> (or whatever).

所以我做了一些网络搜索并找到了这个链接:https://bugreports.qt.io/browse/QTBUG-6345

So I did some web searching and ran into this link: https://bugreports.qt.io/browse/QTBUG-6345

根据 Thiago Macieira 的声明,对不起,我们不会支持这样构建 Qt",我一直担心修复 Qt 使其像其他任何东西一样工作可能会导致一些问题,并一直试图避免它.我们使用/Zc:wchar_t- 标志重新编译了我们所有的支持库,直到几天前我们开始尝试移植(我们正在从 Wx 切换到 Qt)一些序列化时,我们对此感到相当满意代码.

Based on the statement by Thiago Macieira, "Sorry, we will not support building Qt like this," I've been worried that fixing Qt to work like everything else might cause some problem and have been trying to avoid it. We recompiled all of our support libraries with the /Zc:wchar_t- flag and have been fairly content with that until a couple days ago when we started trying to port over (we're in the process of switching from Wx to Qt) some serialization code.

由于 win32 的工作方式,并且因为 Wx 只是包装了 win32,我们一直使用 std::wstring 来表示字符串数据,目的是使我们的产品尽可能为 i18n 做好准备.我们做了一些测试,当尝试打印特殊的东西时,Wx 不能处理多字节字符(即使不是像度数符号这样特殊的东西也是一个问题).我不太确定 Qt 是否存在这个问题,因为 QString 不仅仅是底层 _TCHAR 类型的包装器,而且还是某种 Unicode 怪物.

Because of how win32 works, and because Wx just wraps win32, we've been using std::wstring to represent string data with the intent of making our product as i18n ready as possible. We did some testing and Wx did not work with multibyte characters when trying to print special stuff (even not so special stuff like the degree symbol was an issue). I'm not so sure that Qt has this problem since QString isn't just a wrapper to the underlying _TCHAR type but is a Unicode monster of some sort.

无论如何,boost中的序列化库已经编译了部分.我们已经尝试使用/Zc:wchar_t- 重新编译 boost,但到目前为止,我们试图告诉 bjam 这样做的尝试都没有受到重视.我们陷入了僵局.

At any rate, the serialization library in boost has compiled parts. We've attempted to recompile boost with /Zc:wchar_t- but so far our attempts to tell bjam to do this have gone unheeded. We're at an impasse.

从我坐的位置,我有三个选择:

From where I'm sitting I have three options:

  1. 重新编译 Qt 并希望它适用于/Zc:wchar_t.网络上有一些证据表明其他人已经这样做了,但我无法预测会发生什么.所有在论坛上询问 Qt 人员的尝试都没有得到答复.见鬼,即使在那个错误报告中,也有人问为什么,它就在那里呆了一年.

  1. Recompile Qt and hope it works with /Zc:wchar_t. There's some evidence around the web that others have done this but I have no way of predicting what will happen. All attempts to ask Qt people on forums and such have gone unanswered. Hell, even in that very bug report someone asks why and it just sat there for a year.

继续与 bjam 战斗,直到它听到为止.现在我已经有人在我手下这样做了,而且我有更多的经验与事物作斗争以获得我想要的东西,但我不得不承认我已经相当厌倦了.我也担心我会继续遇到这个问题,因为 Qt 想成为一个 c**t.

Keep fighting with bjam until it listens. Right now I've got someone under me doing that and I have more experience fighting with things to get what I want but I do have to admit to getting rather tired of it. I'm also concerned that I'll KEEP running into this issue just because Qt wants to be a c**t.

停止使用 wchar_t 做任何事情.不幸的是,我的 i18n 体验几乎为 0,但在我看来,我只需要在 QString(它有一个 BUNCH)中找到正确的 to/from 函数即可将 Unicode 编码为 8 字节,反之亦然.UTF8 函数看起来很有希望,但我真的想确保如果来自某个地方的人使用更符号化的语言开始用他们自己的语言编写并且 QString 中的文档让我有点害怕认为可能发生的情况,则不会丢失任何数据.当然,我总是会遇到一些坚持使用 wchar_t 的库,然后我又回到了 1 或 2,但我很怀疑这会发生.

Stop using wchar_t for anything. Unfortunately my i18n experience is pretty much 0 but it seems to me that I just need to find the right to/from function in QString (it has a BUNCH) to encode the Unicode into 8-bytes and visa-versa. UTF8 functions look promising but I really want to be sure that no data will be lost if someone from someplace with a more symbolic language starts writing in their own language and the documentation in QString frightens me a little into thinking that could happen. Of course, I could always run into some library that insists I use wchar_t and then I'm back to 1 or 2 but I rather doubt that would happen.

那么,我的问题是什么...

So, what's my question...

这些选项中哪个是我最好的选择?Qt 最终会不会因为我决定用/Zc:wchar_t 编译它而导致我挖出自己的眼睛?

Which of these options is my best bet? Is Qt going to eventually cause me to gouge out my own eyes because I decided to compile it with /Zc:wchar_t anyway?

使用/Zc:wchar_t- 增强建造的魔法咒语是什么,这会造成永久性的精神伤害吗?

What's the magic incantation to get boost to build with /Zc:wchar_t- and will THAT cause permanent mental damage?

我可以只使用标准的 8 位(好吧,无论如何都是通用")字符类并符合 i18n 标准/准备好了吗?

Can I get away with just using the standard 8-bit (well, 'common' anyway) character classes and be i18n compliant/ready?

其他 Qt 开发人员如何处理这个烂摊子?

How do other Qt developers deal with this mess?

推荐答案

偶然发现了同样的问题...显然 bjam 期望 cxxflags=-Zcwchar_t-

Stumbled over the same issue ... Obviously bjam expects cxxflags=-Zcwchar_t-

通过

bjam --with-serialization toolset=msvc-8.0 variant=debug threading=multi link=static cxxflags=-Zc:wchar_t-

一切都像预期的一样.

希望对大家有所帮助.

相关文章