源码必须是UTF-8,QString需要它

妖精的绣舞 提交于 2020-01-07 15:51:32

源码必须是UTF-8,QString需要它

来源 https://www.qt.io/cn/blog/2012/05/16/source-code-must-be-utf-8-and-qstring-wants-it

 

Published on Wednesday May 16, 2012 by Debao Zhang in C++Qtqtearth-blogs-chinese | Comments

原文链接:Thiago Macieira- Source code must be UTF-8 and QString wants it

先前我讨论过源代码的编码问题,认为C++语言缺少一个必要的基本设置。尽管如此,从本周一开始,在某种程度上,Qt5现在已开始强制要求源代码必须是UTF-8。

将QString的8-bit成员函数所用的编码改为UTF-8的提交(commit)终于融入到qtbase代码仓库中。这正是我们为Qt5所规划的,从Robin Burchell移除QTextCodec::setCodecForCStrings开始的,一系列变更(changes)画上了完美的句号。但明确一点:QString内部仍采用UTF-16存储数据且不会改变。

 

为了理解这个变更是什么,我们需要回顾一点点历史。四年前,我写了一篇叫做“字符串理论(String Theory)”的博客来介绍QString的历史。我写到:

你的文件是何种编码?即便是UTF-8被广泛使用的今天,我们仍然不能依赖于这个事实(Windows下的文本编辑器是最糟糕的例子)。

在2008年,我们仍然与源代码中的UTF-8编码抗争,和我们在2003年所做的一样,当时QTextCodec::setCodecForCStrings被引入到Qt3。原因是,在当时,文本编辑器通常只使用操作系统的本地(locale)编码来保存代码,而且很少支持编写其它东西。由于Unicode尚未被广泛使用,从而导致人们使用各种不同的编码。考虑到数据交换只在使用相同编码的人(来自同一个国家,使用相同的操作系统)之间发生,这在当时也不是个问题。

时代已经改变了。源于90年代后期哪些不具备编码标示的协议很快就变得过时了或者增加这种标记(我记得当时Kopete的开发者正挣扎于如何恰当地解码ICQ消息,而且俄罗斯用户通常以乱码(mojibake)结束)。设计于21世纪的协议都有一个此类标示,而且很快基于某个Unicode transforms形成规范。

去年,当重新审视这个主题时,我写到:

都2011了,为什么我们仍将自己限制在ASCII?我是说,即使你只是用英文写不需要翻译的消息,有时你仍需要非ASCII码点(codepoint),比如“微”符号(µ),度符号(°),版权符号(©),甚至是欧元符号(€)。[...]。除此之外,现在是2011,文字交换的事实(de-facto)编码是UTF-8。

博客中下一行就是结论:在Qt5中,我们将把QString的8位(8-bit)成员函数的默认编码从Latin 1改为UTF-8(注意到,直到15天以后我们才开始思考Qt 5)。这就是我本周一的提交(commit)最终完成的事情。

这对你意味着什么呢?好吧,第一件事情是它依赖于你是否使用了这些成员方法。如果你编译源代码时使用了宏QT_NO_CAST_FROM_ASCIIQT_NO_CAST_TO_ASCII,你将感受不到任何区别。我的意思真的是完完全全,彻彻底底:如果你使用了这些宏,你已经禁用了所有受我的变更所影响的函数。

如果你真的使用了被这些宏所禁用的函数,那么问题是这些字符串使用的何种编码。我在2008所做的假设现在仍然有效:源代码中的绝大多数字符串是7-bit,US-ASCII,英文文字。这些7-bit的文字完全不受影响:它将向往常一样被转换成QString的内部编码UTF-16。这可能会影响一点点性能,但就像我去年所说,我确实有优化UTF-8解码器的计划。尽管如此,如果你可以,我建议使用QLatin1String来封装这些字符串,尤其是你正将它们用于一个有QLain1String重载的QString的函数。

另一方面,如果你确实在QString的8-bit成员函数中使用了高位被设置的的文字,你可能需要修改你的代码。你要么用UTF-8重写你的代码,要么你需要用合适的QLatin1StringQTextCodec::toUnicode函数来封装这些字符串。我比较建议使用前一个选项:在你的源代码中使用UTF-8。你也将获得正确使用QStringLiteral的能力,无论如何,它需要源代码是UTF-8。

[作为历史的一个有趣的转折点,QStringLiteral的灵感源于我去年第二篇关于编码的博客——在本文前面所引用的要求改为UTF-8的第一部分之后,但它比本周一的变更更早地融入Qt 5之中。]

对于Qt自身的源码,我们已经决定应当只使用UTF-8,而且从几周前开始我一直在搜索并重写所有的非UTF-8的源码。
我将更进一步:如果你在自己的源码中不使用UTF-8,你需要自己负责。尽管使其工作是可能的,但不要向我们寻求帮助,也不要期待我们为其添加便利的函数。我也会忽略任何这种形式的争论“我的编辑器、IDE、OS、环境不支持UTF-8”。现在是2012而且我们生活在一个全球化的世界。任何此类的编辑器或环境应该留在属于它的地方:一个致力于上世纪80年代和90年代的博物馆。

Unicode万岁!

 

------------------------

来源 https://doc.qt.io/archives/qt-4.8/qstring.html

Macro Documentation

QT_NO_CAST_FROM_ASCII

Disables automatic conversions from 8-bit strings (char *) to unicode QStrings

See also QT_NO_CAST_TO_ASCII and QT_NO_CAST_FROM_BYTEARRAY.

QT_NO_CAST_TO_ASCII

disables automatic conversion from QString to 8-bit strings (char *)

See also QT_NO_CAST_FROM_ASCII and QT_NO_CAST_FROM_BYTEARRAY.

 

# DEFINES: 宏定义集合
DEFINES += QT_NO_CAST_FROM_ASCII
DEFINES += QT_NO_CAST_FROM_BYTEARRAY
DEFINES += QT_NO_CAST_TO_ASCII
DEFINES += QT_NO_URL_CAST_FROM_STRING
DEFINES += QT_USE_QSTRINGBUILDER

# QT_DEPRECATED_WARNINGS: 使用不推荐或废弃模块时,产生对应的警告信息
# The following define makes your compiler emit warnings if you use
# any Qt feature that has been marked deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS

# QT_DISABLE_DEPRECATED_BEFORE: 使用不推荐或废弃模块时,在指定QT版本之前禁用对应的警告信息
# You can also make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0

 

==================== End

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!