Литералы wchar_t, отличные от ASCII, в LLVM

Я перенес проект Xcode iOS с Xcode 3.2.6 на 4.2. Теперь я получаю предупреждения, когда пытаюсь инициализировать wchar_t литералом с символом, отличным от ASCII:

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

Сообщения следующие:

MyFile.cpp: 148: 28: предупреждение: escape-последовательность символов Unicode слишком длинная для своего типа [2] MyFile.cpp: 148: 28: warning: игнорируются посторонние символы в константе широких символов [2]

И буквальный не работает должным образом - сравнение не выполняется.

Я компилирую с -fshort-wchar, исходный файл находится в UTF-8. Редактор Xcode отлично отображает файл. Он компилировался и работал на GCC (несколько разновидностей, включая Xcode 3), работал на MSVC. Есть ли способ заставить компилятор LLVM распознавать эти литералы? Если нет, могу ли я вернуться к GCC в Xcode 4?

РЕДАКТИРОВАТЬ: Xcode 4.2 на Snow Leopard - длинная история почему.

EDIT2: подтверждено в новом проекте. Расширение файла не имеет значения - такое же поведение в файлах .m. -fshort-wchar тоже не влияет на это. Похоже, мне нужно вернуться в GCC, пока я не смогу перейти на версию Xcode, где это исправлено.


person Seva Alekseyev    schedule 26.10.2012    source источник
comment
В какой версии Xcode 4 это? Какой компилятор будет использовать ваш проект?   -  person bames53    schedule 26.10.2012
comment
Это похоже на связанную ошибку.   -  person Jesse Good    schedule 26.10.2012


Ответы (3)


Если на самом деле источник - UTF-8, то это неправильное поведение. Однако я не могу воспроизвести поведение в самой последней версии Xcode.

MyFile.cpp: 148: 28: предупреждение: escape-последовательность символов Unicode слишком длинная для своего типа [2]

Эта ошибка должна относиться к «универсальному символьному имени» (UCN), которое выглядит как «\ U001012AB» или «\ u0403». Это указывает на то, что значение, представленное escape-последовательностью, больше, чем может удерживать включающий тип литерала. Например, если значение кодовой точки требует более 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. Вы также можете попробовать переключить компилятор в настройках вашего проекта> Компиляция для C / C ++ / Objective-C

person bames53    schedule 26.10.2012
comment
Я согласился, потому что ответ содержит правильную рекомендацию либо обновить Xcode, либо переключить компилятор обратно на GCC. Последний точно работает, первый работал на Влада. Но настоящий ответ здесь - это комментарий Джесси Гуда. - person Seva Alekseyev; 26.10.2012
comment
@SevaAlekseyev Хорошо, похоже, что версия clang, которую вы используете, была до того, как clang переместился на использование UTF-8 в качестве входного набора символов. Поддержка символьных и строковых литералов UTF-8 была добавлена ​​некоторое время назад. - person bames53; 26.10.2012

Не ответ, но, надеюсь, полезная информация - я не смог воспроизвести проблему с 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 - встроенный тип).

person Community    schedule 26.10.2012

У меня нет ответа на ваш конкретный вопрос, но я хотел бы отметить, что поддержка llvm-gcc была окончательно прекращена. По моему опыту работы с дельтами между Clang и llvm-gcc и gcc, Clang часто бывает правильным в отношении спецификации C ++, даже если такое поведение вызывает удивление.

person 0-0    schedule 26.10.2012