Qt, MSVC, and /Zc:wchar_t- == I want to blow up the world
Asked Answered
L

4

37

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.

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).

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

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.

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.

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. 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.

  2. 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.

  3. 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...

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?

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

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

How do other Qt developers deal with this mess?

Lictor answered 23/12, 2010 at 18:2 Comment(2)
+1 For blowing the world up. (The Vogons and I beat you to it, though. I've done it 42 times, and my Vogon buddy's only got a score of 37.)Imprudent
This is one of those problems that doesn't sound like a big deal until you come face to face with it. I'm stuck with Qt4 for now, but it seems this has been fixed in 5.0.0. For now, the third option you describe seems like the only viable option.Wits
O
6

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

After building the static serialization libs via

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

everything linked like expected.

Hope this helps anyone.

Orangy answered 10/2, 2011 at 12:0 Comment(1)
See also boost.2283326.n4.nabble.com/….Galloot
K
7

I would agree with Öö Tiib's remark

That option is perhaps for compatibility with some old legacy pre-wchar_t code.

Having in mind that Qt is ported to many different platforms (including embedded systems), some of them not having a decent C++ compiler, I would guess that this switch is just to make it possible to compile Qt on those platforms. I mean it's probably not something that Qt relies on to work correctly. If it were the case it would mean that Qt's design is deeply broken in my opinion. So option 1 should work.

Having said that I would definitely recommend choosing option 3 because

  • wchar_t gives you almost nothing in regard to i18n
  • as you noticed Qt has very capable string class which makes i18n an easy task (see Internationalization with Qt)

You might take a look at results of searching for wchar_t on [email protected] list, ask your question there and talk to Thiago Macieira on freenode.net #qt irc channel where Thiago is very active.

Krause answered 24/12, 2010 at 11:41 Comment(0)
O
6

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

After building the static serialization libs via

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

everything linked like expected.

Hope this helps anyone.

Orangy answered 10/2, 2011 at 12:0 Comment(1)
See also boost.2283326.n4.nabble.com/….Galloot
C
1

Putting this here as an answer because it's too long for comment.

Here's one of the answers to why one might be getting LNK2019 aka "symbol not found" linker error (source):

  • You mix code that uses native wchar_t with code that doesn't. C++ language conformance work that was done in Visual C++ 2005 made
    wchar_t a native type by default. You must use the /Zc:wchar_t-
    compiler option to generate code compatible with modules compiled by
    using earlier versions of Visual C++. If not all modules have been
    compiled by using the same /Zc:wchar_t settings, type references may
    not resolve to compatible types. Verify that wchar_t types in all
    modules are compatible, either by updating the types that are used,
    or by using consistent /Zc:wchar_t settings when you compile.

So that could be the main reason why /Zc:wchar_t- is there in all cl.exe-related mkspec files and also why you probably don't need it.

I like having native wchar_t because it makes it sometimes easy to convert between the strings that the windows api expects and QString.

Construe answered 20/7, 2015 at 23:5 Comment(0)
C
-1

wchar_t should be type like bool or long. No headers are needed to define it.

You did use that "wchar_t is undefined type" option. Then you typedef wchar_t as unsigned short and then you wonder that nothing works anymore?

That option is perhaps for compatibility with some old legacy pre-wchar_t code. Just simply ... never use it. Otherwise nothing C++ links to it because functions that take wchar_t parameters are differently name-mangled than functions that take unsigned short parameters.

If some library is compiled with some strange options then build it with correct options. When needed then fix its code. If you can not do it then you should not use that library. Every line of code in your C++ project is yours to maintain.

Cosmography answered 23/12, 2010 at 18:42 Comment(4)
This is a beautiful example of a mathematician's answer. You are basically asking the OP to fix an unknown number of difficult-to-pin-down bugs in an enormous library, and to maintain said fixes indefinitely, against the wishes of the library authors.Stowers
There are no libraries without bugs. On windows QT works smoothly. Just try to write an QT application on Nokia cellphone with that strange hand-held Symbian OS in it to find out what constant maintenance of someone elses trash really means.Dael
@Zac - yeah, I thought the "don't use it" answer was pretty cute when I was asking how to deal with someone ELSE using it in as easy a way possible. Didn't notice the edit until now...cute; probably safe to say that Oo doesn't code for a living.Lictor
Well. If you use other's code and pay them nothing for maintenance then it is yours to maintain. Be it boost or QT. No need to insult me if you don't like that answer.Dael

© 2022 - 2024 — McMap. All rights reserved.