GCC и CLang не распознают строку Unicode

Я передаю GCC строку UTF-32, и он жалуется на недопустимый многобайтовый или широкий символ.

Я проверил это в Clang и получил то же сообщение об ошибке.

Первоначально я написал оператор с помощью MSVC, и он работал нормально.

Вот утверждение утверждения.

 assert(utf_string_copy_utf32(&string, U"¿Cómo estás?") == 0);

Вот декларация.

int utf_string_copy(struct utf_string * a, const char32_t * b);

Вот команда компиляции:

cc -Wall -Wextra -Werror -Wfatal-errors -g -I ../include -fexec-charset=UTF-32 string-test.c libutf.a -o string-test

Должен ли я предположить, что GCC может распознавать символы Unicode только по управляющим последовательностям?

Или я неправильно понимаю, как GCC и CLang распознают эти символы.

Изменить 1

Вот сообщение об ошибке.

string-test.c: In function ‘test_copy’:
string-test.c:46:61: error: converting to execution character set: Invalid or incomplete multibyte or wide character
assert(utf_string_copy_utf32(&string, U"�C�mo est�s?") == 0);

Редактировать 2

Я еще больше запутался, когда попытался воссоздать ошибку в меньшем примере.

#include <uchar.h>
#include <stdlib.h>
#include <stdio.h>

static size_t test_utf8(const char * in){
    size_t len;
    for (len = 0; in[len]; len++);
    return len;
}

static size_t test_utf32(const char32_t * in){
    size_t len;
    for (len = 0; in[len]; len++);
    return len;
}

int main(void){
    size_t len;

    len = test_utf8(u8"¿Cómo estás?");
    printf("utf-32 length: %lu\n", len);

    len = test_utf32(U"¿Cómo estás?");
    printf("utf-32 length: %lu\n", len);

    return 0;
}

Это печатает:

utf-8 length: 15
utf-32 length: 12

Это подтверждает то, как я изначально думал, что это работает.

Так что я предполагаю, что это означает, что где-то в коде библиотеки, которую я использую, есть проблема. Но я до сих пор понятия не имею, что происходит.


person tay10r    schedule 26.02.2017    source источник
comment
Возможно актуально: stackoverflow.com/questions/3768363/character-sets-not -очистить   -  person hyde    schedule 26.02.2017
comment
Ваш вопрос, кажется, трансформировался из string-test.c:46:61: error: converting to execution character в вопрос, почему длина отличается? Каков ваш фактический вопрос?   -  person Soren    schedule 26.02.2017
comment
Мой вопрос заключался в том, почему я получаю сообщение об ошибке. Я понял. Я сейчас пишу ответ.   -  person tay10r    schedule 26.02.2017
comment
Вы, вероятно, захотите использовать редактор, который может писать исходный код UTF-8, если вы собираетесь использовать u8"literals"   -  person M.M    schedule 26.02.2017
comment
@MM не имеет значения, закодирована ли строка u8"" как UTF-8 в исходном коде. Имеет значение только то, что исходный код использует одну и ту же кодировку во всем файле и что компилятор знает, какую кодировку ожидать. Например, GCC действительно поддерживает набор символов Windows-1252, его просто нужно указать в командной строке.   -  person tay10r    schedule 26.02.2017


Ответы (1)


Я понял проблему.

Я сделал шестнадцатеричный дамп обоих строковых литералов (строковый литерал, который ломался в исходном коде, и строковый литерал, который работал).

Вот неработающий строковый литерал (я написал это в Windows):

00000000: 5522 bf43 f36d 6f20 6573 74e1 733f 220a  U".C.mo est.s?".

Вот рабочий строковый литерал (я написал это на машине с Ubuntu):

00000000: 5522 c2bf 43c3 b36d 6f20 6573 74c3 a173  U"..C..mo est..s
00000010: 3f22 0a                                  ?".

Хотя они выглядят совершенно одинаково в редакторе кода, и хотя они оба имеют префикс U, в исходном коде они кодируются по-разному.

И хотя я не совсем уверен, какая кодировка какая, я понял, что проверка кодировки исходного кода литерала очень, очень важна.

Изменить 1

Как отметил @melpomene в комментариях:

Нарушена кодировка Windows-1252.

Рабочая кодировка — UTF-8.

person tay10r    schedule 26.02.2017
comment
Неработающий находится в Windows-1252; рабочий — в UTF-8. - person melpomene; 26.02.2017
comment
@melpomene Спасибо! - person tay10r; 26.02.2017
comment
Это не сломано, вам просто нужно сообщить компилятору, что такое исходная кодировка. Я считаю, что это с -finput-charset. - person Mark Tolonen; 27.02.2017
comment
Я настоятельно рекомендую использовать UTF-8 везде, где это возможно. Современные цепочки инструментов также не должны ругаться на спецификацию, но вы можете попробовать поместить ее в комментарий, если что-то произойдет. - person Davislor; 27.02.2017