llvm下的非ASCII WCHAR_T文字

Non-ASCII wchar_t literals under LLVM

本文关键字:文字 WCHAR ASCII llvm      更新时间:2023-10-16

我已经从xcode 3.2.6到4.2迁移了Xcode iOS项目。现在,当我试图用具有非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吗?

编辑:Xcode 4.2在雪豹上 - 长篇小说为什么。

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

不是答案,但希望有帮助的信息 - 我无法通过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) == %lun", sizeof(c1));
    printf("sizeof(L'Я') == %lun", 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是内置类型)。

如果源实际上是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,更不用说" f"很容易在单个16位WCHAR_T中适合的事实;第二,因为他的源代码编码始终被视为UTF-8,并且将" UTF-8的多键表示"视为单个codepoint。

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

编译

我对您的特定问题没有答案,但想指出LLVM-GCC已永久停止。根据我在Clang和LLVM-GCC之间与Delta打交道的经验,而GCC在C 规范方面通常是正确的。