各C/C++编译器对wchar_t字符和字符串的正确支持程度

转自:http://blog.csdn.net/longsong/archive/2007/12/02/1912201.aspx

 

 

      传统的C风格的字符串是以字符 '/0 '为结尾的一系列字节的集合,其一个单元为char类型,可以保存世界上的几百种不同的字符集,包括ASCII、ISO-8859、GBK、BIG-5、SHIFT-JIS、UTF-8等等。通常这些字符集都是兼容ASCII字符集的。我们可以把这些兼容ASCII字符集统称为ANSI字符集。正因为各种不同的字符集的存在,所以在实际的使用中会产生各种缺字和乱码的现象。

 

      Unicode是包含世界上各种语言和符号的编码。 

      在实际应用中,Unicode以UTF-8和UTF-16、UTF-32这三种形式存在,这三种形式都可以完美地表示Unicode的各个码位。 

      例如:中文的 "中 "字,其Unicode码位为U+4E2D,用UTF-8用三个8位的字节来表示为:0xE4   0xB8   0xAD,UTF-16则使用一个16位的整数0x4E2D来表示,UTF-32则使用一个32位的整数0x00004E2D来表示。(当字符码位大于0xFFFF时,UTF-8要用四个8位的字节来表示,UTF-16需要使用2个16位整数来表示)

 

      UTF-16与UTF-32相比,UTF-16显得更加简洁。Windows下普遍使用UTF-16,而Linux和其它Unix类的系统由于历史上的设计原因,则比较倾向于使用UTF-8和UTF-32这两种传输方式。 

 

      C/C++标准均已经提供了wchat_t关键字来实现对Unicode的支持,而且wchat_t类型只用于Unicode编码。在Windows平台下,wchat_t类型是16位的;而在Linux下,wchat_t类型是32位的。 

 

      下面以Windows   x86平台下为例子,说明wchar_t字符串在内存中的存储形式: 

      例如下面一个UTF-16字符串: 

                  wchar_t   str[]=L "中文 "; 

      上面是一个UTF-16的字符串,是分别由0x4E2D,0x6587,0x0000所组成的串。因为x86的CPU是低字节在前的(Little   Endian),所以该wchar_t串在内存中的存储为:2D   4E   87   65   00   00。 

 

      Unicode在C/C++中就是这么简单的表示用法,在某些的C/C++编译器中,却不能完善支持,下面就列举各C/C++编译器对wchar_t字符和字符串的支持程度:

 

 

(1)Visual   C/C++ 

      Visual   C/C++的编译器对Unicode的支持是最完美的,Microsoft是Unicode的创造者之一,也是极力推荐使用Unicode编码的公司。 

      Visual   C/C++除了完美支持wchar_t类型外,Visual   C++   7.0或者更新版本的编译器还可以接受UTF-8/UTF-16编码格式的源代码文件。

 

 

(2)Borland   C/C++ 

        Borland   C/C++的编译器对Unicode的支持也是完美的,从1994年的Borland   C++   4.5开始,Borland   C/C++的编译器就能正确处理wchar_t字符和字符串。 

        C++Builder   6.0的编译器还添加了   -CP   参数来支持各种不同Codepage的源代码。 

        C++Builder   2006还可以支持UTF-8编码格式(带BOM)的源代码文件,但是不支持UTF-16编码格式的源代码文件。

 

 

(3)gcc 

        GNU   C/C++编译器也可以正确支持wchar_t字符和字符串,但是源代码的保存格式必须符合下面条件: 

        一、源代码文件的保存编码必须是UTF-8 

        二、UTF-8编码格式的源代码文件,不能有BOM标志头。 

        只有源代码文件符合上面两个条件,gcc才会正确支持wchar_t字符和字符串。如果不符合上面两个条件的话,有可能会编译出错,有可能会产生错误的wchar_t字符和字符串。 

        gcc在Windows平台下,wchar_t是16位类型,在Linux平台下,wchar_t是32位类型。 

 

        另外,GCC提供了以下的参数开关来支持其它文字编码的源文件:

        (a)-finput-charset=charset

            gcc在默认情况下,总是假设源代码的编码是UTF-8,如果是其它编码的源代码文件, 源代码里面又用到了wchar_t的类型,则可以使用-finput-charset=charset这个参数来实现。

            例如通常使用GBK编码的源代码可以假如参数:-finput-charset=GBK

         (b)-fwide-exec-charset=charset

            默认情况下,gcc在Windows平台下,宽字符串串常量的每个字符是16位UTF-16类型,在Linux平台下,宽字符串串常量的每个字符是32位UTF-32类型,  使用这个参数,可以改变宽字符串串常量的类型。

            例如在x86的机器环境,Linux操作系统下,要使例如 L"汉字" 编译后保存为UTF-16的字符串,则可以使用 -fwide-exec-charset=UTF-16LE

 

(4)Digital   Mars   C/C++ 

        Digital   Mars   C/C++   的前身是Symantec   C/C++。 

        Digital   Mars   C/C++也可以正确支持wchar_t字符和字符串。 

        但是Digital   Mars   C/C++不能接受UTF-8(带BOM)、UTF-16编码格式的源代码文件。

 

 

(5)OpenWatcom   C/C++ 

        OpenWatcom   C/C++不支持wchar_t字符和字符串。 

        虽然OpenWatcom   C/C++在处理wchar_t字符和字符串时,不会编译错误,但是所产生的wchar_t字符和字符串确实错误的。 

        OpenWatcom   C/C++也不能接受UTF-8(带BOM)、UTF-16编码格式的源代码文件。 

        OpenWatcom可以说是对Unicode支持最差的编译器。 

 

 

(6)Intel   C/C++ 

        和Visual   C++差不多。 

        是否支持UTF-8/UTF-16编码格式的源代码文件,本人则没有进行详细的测试。 

 

 

(6)PGI   C/C++ 

        没有对这个编译器进行详细的测试,但是PGI   C/C++的前端是来自gcc,理论上应该跟gcc相差不远。 

 

 

你可能感兴趣的:(windows,linux,gcc,Microsoft,编译器,Borland)