Подтвердить что ты не робот

Qt, MSVC и /Zc: wchar_t- == Я хочу взорвать мир

Итак, Qt скомпилирован с /Zc: wchar_t- на окнах. Это означает, что вместо wchar_t является typedef для некоторого внутреннего типа (__wchar_t, я думаю), он становится typedef для unsigned short. Самое замечательное в этом заключается в том, что значение по умолчанию для MSVC - это противоположное, что, конечно же, означает, что используемые библиотеки, скорее всего, скомпилированы с wchar_t другим типом, чем Qt wchar_t.

Это не станет проблемой, пока вы не попытаетесь использовать что-то вроде std::wstring в своем коде; особенно когда одна или несколько библиотек имеют функции, которые принимают ее как параметры. Эффективно получается, что ваш код с удовольствием компилируется, но затем не связывается, потому что ищет определения с помощью std::wstring<unsigned short...>, но они содержат только определения, ожидающие std::wstring<__wchar_t...> (или что-то еще).

Итак, я сделал несколько поисков в Интернете и наткнулся на эту ссылку: https://bugreports.qt.io/browse/QTBUG-6345

Основываясь на заявлении Thiago Macieira, "Извините, мы не будем поддерживать построение Qt, как это", я был обеспокоен тем, что исправление Qt для работы, как и все остальное, может вызвать некоторые проблемы и пытаться избежать этого. Мы перекомпилировали все наши библиотеки поддержки с флагом /Zc: wchar_t- и были достаточно довольны этим до тех пор, пока пару дней назад, когда мы начали пытаться выполнить перенос (мы переходим от Wx к Qt), некоторые сериализации код.

Из-за того, как работает win32, и поскольку Wx просто обертывает win32, мы использовали std::wstring для представления строковых данных с намерением сделать наш продукт максимально готовым. Мы провели некоторое тестирование, и Wx не работал с многобайтными символами при попытке распечатать специальные материалы (даже не такие специальные вещи, как символ степени, был проблемой). Я не уверен, что у Qt есть эта проблема, поскольку QString - это не просто оболочка для базового типа _TCHAR, а монстра Unicode.

Во всяком случае, библиотека сериализации в boost скомпилировала части. Мы попытались перекомпилировать boost с помощью /Zc: wchar_t-, но до сих пор наши попытки сказать bjam сделать это остались без внимания. Мы в тупике.

Откуда я сижу, у меня есть три варианта:

  • Перекомпилируйте Qt и надейтесь, что он работает с /Zc: wchar_t. Там есть некоторые доказательства в Интернете, которые другие сделали это, но я не могу предсказать, что произойдет. Все попытки спросить Qt людей на форумах и т.д. Остались без ответа. Черт, даже в этом очень сообщении об ошибке кто-то спрашивает, почему, и он просто сидел там год.

  • Продолжайте сражаться с bjam, пока он не слушает. Прямо сейчас у меня есть кто-то, кто делает это, и у меня больше опыта борьбы с вещами, чтобы получить то, что я хочу, но я вынужден признать, что устал от этого. Я также обеспокоен тем, что я буду использовать эту проблему только потому, что Qt хочет быть c ** t.

  • Прекратите использование wchar_t для чего-либо. К сожалению, мой опыт i18n в значительной степени равен 0, но мне кажется, что мне просто нужно найти право на/из функции в QString (он имеет BUNCH) для кодирования Unicode в 8-байтный и наоборот. Функции UTF8 выглядят многообещающими, но я действительно хочу быть уверенным, что никакие данные не будут потеряны, если кто-то из Zimbabfuckegypt начнет писать на своем родном языке, а документация в QString немного пугает меня мыслью о том, что это может произойти. Конечно, я всегда мог столкнуться с какой-то библиотекой, которая настаивает на том, что я использую wchar_t, а затем возвращаюсь к 1 или 2, но я скорее сомневаюсь, что это произойдет.

Итак, что мой вопрос...

Какой из этих вариантов - мой лучший выбор? Может ли Qt в конечном итоге заставить меня вытолкнуть мои собственные глаза, потому что я решил скомпилировать его с помощью /Zc: wchar_t?

Какое магическое заклинание должно быть усилено для создания с помощью /Zc: wchar_t- и будет ли это причинять постоянный умственный ущерб?

Могу ли я обойтись просто с использованием стандартных 8-битных (ну, "обычных" ) классов символов и быть совместимым/готовым i18n?

Как другие разработчики Qt справляются с этим беспорядком?

4b9b3361

Ответ 1

Я согласен с замечанием Öö Tiib

Этот вариант, возможно, для совместимость с каким-то старым наследием pre-wchar_t.

Имея в виду, что Qt переносится на многие разные платформы (включая встроенные системы), некоторые из них не имеют достойного компилятора С++, я бы предположил, что этот коммутатор просто позволяет компилировать Qt на этих платформах. Я имею в виду, что это, вероятно, не то, что Qt полагается на правильную работу. Если бы это было так, это означало бы, что дизайн Qt глубоко нарушен, на мой взгляд. Поэтому вариант 1 должен работать.

Сказав, что я определенно рекомендую выбрать вариант 3, потому что

  • wchar_t дает вам почти ничего отношение к i18n
  • поскольку вы заметили, что Qt имеет очень способный класс строк что делает задачу легкой (см. Интернационализация с Qt)

Вы можете взглянуть на результаты поиска wchar_t на [email protected], задайте свой вопрос там и поговорите с Тьяго Масиейрой на freenode.net #qt irc, где Тьяго очень активен.

Ответ 2

Наткнулся на ту же проблему... Очевидно, что bjam ожидает cxxflags=-Zcwchar_t-

После создания статических сериализационных библиотек через

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

все связано как ожидалось.

Надеюсь, это поможет кому угодно.

Ответ 3

wchar_t должен быть типом типа bool или long. Для его определения не требуются заголовки.

Вы использовали этот параметр "wchar_t is undefined type". Затем вы вводите typedef wchar_t как unsigned short, а затем задаетесь вопросом, что больше ничего не работает?

Этот вариант, возможно, совместим с каким-то старым предыдущим кодом pre-wchar_t. Просто... никогда не используйте его. В противном случае ни на что С++ не ссылается на него, потому что функции, которые принимают параметры wchar_t, по-разному управляются именами, чем функции, которые принимают неподписанные короткие параметры.

Если какая-либо библиотека скомпилирована с некоторыми странными параметрами, то создайте ее с правильными параметрами. Когда необходимо, исправьте его код. Если вы не можете этого сделать, вы не должны использовать эту библиотеку. Каждая строка кода в вашем проекте на С++ поддерживается вами.

Ответ 4

Поместите это здесь как ответ, потому что он слишком длинный для комментариев.

Вот один из ответов на вопрос о том, почему LNK2019 может быть заменен как "символ не найден" (источник):

  • Вы смешиваете код, который использует собственный wchar_t с кодом, который этого не делает. Работа по совместимости языка С++, которая была выполнена в Visual С++ 2005, сделана
    По умолчанию используется wchar_t собственный тип. Вы должны использовать /Zc: wchar_t-
    компилятор для генерации кода, совместимого с модулями, скомпилированными с помощью используя более ранние версии Visual С++. Если не все модули были скомпилированные с использованием тех же настроек /Zc: wchar_t, типы ссылок могут быть указаны не разрешать совместимые типы. Убедитесь, что типы wchar_t во всех
    модули совместимы либо путем обновления типов, которые используются,
    или с помощью параметров согласованного /Zc: wchar_t при компиляции.

Таким образом, это может быть основной причиной того, почему /Zc: wchar_t- присутствует во всех файлах mkspec, связанных с cl.exe, а также почему вы, вероятно, не нуждаетесь в нем.

Мне нравится иметь native wchar_t, потому что он иногда легко конвертировать между строками, которые ожидаются windows api, и QString.