LLVM下的非ASCII wchar_t文字

时间:2012-10-26 03:27:23

标签: c++ ios xcode4 llvm wchar-t

我已将Xcode iOS项目从Xcode 3.2.6迁移到4.2。现在,当我尝试使用非ASCII字符的文字初始化wchar_t时,我收到警告:

wchar_t c1;
if(c1 <= L'я') //That's Cyrillic "ya"

消息是:

  

MyFile.cpp:148:28:警告:字符unicode转义序列的类型太长[2]   MyFile.cpp:148:28:警告:宽字符常量中的无关字符被忽略[2]

文字不能按预期工作 - 比较失误。

我正在使用-fshort-wchar进行编译,源文件是UTF-8。 Xcode编辑器显示文件正常。它在GCC上编译和工作(包括Xcode 3在内的几种风格),在MSVC上工作。有没有办法让LLVM编译器识别这些文字?如果没有,我可以回到Xcode 4中的GCC吗?

编辑:Snow Leopard上的Xcode 4.2 - 长篇故事。

EDIT2:在一个全新的项目中得到证实。文件扩展名无关紧要 - .m文件中的行为相同。 -fshort-wchar也不会影响它。看起来我必须回到GCC,直到我可以升级到修复版本的Xcode。

3 个答案:

答案 0 :(得分:2)

不是答案,但希望有用的信息 - 我无法用clang 4.0(Xcode 4.5.1)重现问题:

$ uname -a
Darwin air 12.2.0 Darwin Kernel Version 12.2.0: Sat Aug 25 00:48:52 PDT 2012; root:xnu-2050.18.24~1/RELEASE_X86_64 x86_64
$ env | grep LANG
LANG=en_US.UTF-8
$ clang -v
Apple clang version 4.0 (tags/Apple/clang-421.0.60) (based on LLVM 3.1svn)
Target: x86_64-apple-darwin12.2.0
Thread model: posix
$ cat test.c
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
    wchar_t c1 = 0;
    printf("sizeof(c1) == %lu\n", sizeof(c1));
    printf("sizeof(L'Я') == %lu\n", sizeof(L'Я'));
    if (c1 < L'Я') {
        printf("Я люблю часы Заря!\n");
    } else {
        printf("Что за....?\n");
    }
    return EXIT_SUCCESS;
}

$ clang -Wall -pedantic ./test.c 
$ ./a.out 
sizeof(c1) == 4
sizeof(L'Я') == 4
Я люблю часы Заря!
$ clang -Wall -pedantic ./test.c -fshort-wchar
$ ./a.out 
sizeof(c1) == 2
sizeof(L'Я') == 2
Я люблю часы Заря!
$ 

使用clang ++(其中wchar_t是内置类型)观察到相同的行为。

答案 1 :(得分:1)

我对你的具体问题没有答案,但是想指出llvm-gcc已被永久停用。根据我在处理Clang和llvm-gcc以及gcc之间delta的经验,Clang在C ++规范方面经常是正确的,即使这种行为令人惊讶。

答案 2 :(得分:1)

如果实际上源是UTF-8,那么这是不正确的行为。但是,我无法重现最新版本的Xcode中的行为

  

MyFile.cpp:148:28:警告:字符unicode转义序列的类型太长[2]

此错误应引用“通用字符名称”(UCN),其类似于“\ U001012AB”或“\ u0403”。它表示转义序列表示的值大于封闭的文字类型能够容纳的值。例如,如果代码点值需要超过16位,那么16位wchar_t将无法保存该值。

  

MyFile.cpp:148:28:警告:宽字符常量中的无关字符被忽略[2]

这表明编译器认为在宽字符文字中表示了多个代码点。例如。 L'ab'。行为是实现定义的,clang和gcc都只使用最后一个代码点值。

您展示的代码不应该触发其中任何一个,至少在clang中。第一个因为它仅适用于UCN,更不用说“я”很容易适合单个16位wchar_t;第二个因为他的源代码编码总是被认为是UTF-8,它会将'я'的UTF-8多字节表示看作单个代码点。

您可能会重新检查并确保源实际上是UTF-8。然后你应该检查你是否使用了最新版本的Xcode。您也可以尝试在项目设置中切换编译器&gt;编译C / C ++ / Objective-C