Я перенес проект 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-последовательность слишком длинная для его типа [2] MyFile.cpp: 148: 28: предупреждение: посторонние символы в константе широких символов игнорируются [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, в которой это исправлено.
Если на самом деле источником является UTF-8, то это неправильное поведение. Однако я не могу воспроизвести поведение в самой последней версии XCode
MyFile.cpp: 148: 28: предупреждение: символьная escape-последовательность слишком длинная для его типа [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
Не ответ, но, надеюсь, полезная информация — я не смог воспроизвести проблему с 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
встроенный тип).
У меня нет ответа на ваш конкретный вопрос, но я хотел бы отметить, что llvm-gcc был окончательно снят с производства. По моему опыту работы с дельтой между Clang и llvm-gcc и gcc, Clang часто прав в отношении спецификации C ++, даже если такое поведение удивительно.