Возможно ли получить GCC для компиляции UTF-8 с исходными файлами BOM?
Я разрабатываю кросс-платформу С++ с помощью Microsoft Visual Studio для Windows и GCC на uBuntu Linux.
В Visual Studio я могу использовать символы юникода, такие как " π" и " ²" в моем коде. Visual Studio всегда сохраняет исходные файлы как UTF-8 с спецификацией (отметка байтового байта).
Например:
// A = π.r²
double π = 3.14;
GCC с радостью компилирует эти файлы только в том случае, если я сначала удаляю спецификацию. Если я не удаляю спецификацию, я получаю такие ошибки:
wwga_hydutils.cpp: 28: 9: error: stray '\ 317 в программе
wwga_hydutils.cpp: 28: 9: ошибка: блуждание '\ 200 в программе
Что подводит меня к вопросу:
Есть ли способ получить GCC для компиляции файлов UTF-8 без предварительного удаления спецификации?
Я использую:
- Windows 7
- Visual Studio 2010
и
- uBuntu Oneiric 11.10
- GCC 4.6.1 (как указано в apt-get install gcc)
Edit:
Как отметил первый комментатор, моя проблема заключалась в не спецификации, но с символами не-ascii вне строковых констант. GCC не любит символы non-ascii в именах символов, но оказывается, что GCC полностью совместим с UTF-8 с спецификацией.
Ответы
Ответ 1
Согласно GCC Wiki, это пока не поддерживается. Вы можете использовать -fextended-identifiers
и предварительно обработать свой код для преобразования идентификаторов в UCN. На связанной странице:
perl -pe 'BEGIN { binmode STDIN, ":utf8"; } s/(.)/ord($1) < 128 ? $1 : sprintf("\\U%08x", ord($1))/ge;'
См. также имя переменной unicode g++ и Идентификаторы Unicode и исходный код в С++ 11?
Ответ 2
В то время как идентификаторы unicode поддерживаются в gcc, вход UTF-8 - нет. Поэтому идентификаторы Unicode должны кодироваться с помощью escape-кодов\uXXXX и \UXXXXXXXX. Однако простой однострочный патч для препроцессора cpp позволяет gcc и g++ обрабатывать ввод UTF-8 при условии, что также установлена последняя версия iconv, поддерживающая конверсии C99. Детали присутствуют на
https://www.raspberrypi.org/forums/viewtopic.php?p=802657
Однако патч настолько прост, что он может быть задан здесь.
diff -cNr gcc-5.2.0/libcpp/charset.c gcc-5.2.0-ejo/libcpp/charset.c
*** gcc-5.2.0/libcpp/charset.c Mon Jan 5 04:33:28 2015
--- gcc-5.2.0-ejo/libcpp/charset.c Wed Aug 12 14:34:23 2015
***************
*** 1711,1717 ****
struct _cpp_strbuf to;
unsigned char *buffer;
! input_cset = init_iconv_desc (pfile, SOURCE_CHARSET, input_charset);
if (input_cset.func == convert_no_conversion)
{
to.text = input;
--- 1711,1717 ----
struct _cpp_strbuf to;
unsigned char *buffer;
! input_cset = init_iconv_desc (pfile, "C99", input_charset);
if (input_cset.func == convert_no_conversion)
{
to.text = input;
Даже с патчем для включения ввода UTF-8 необходимы две опции командной строки. В частности, попробуйте что-то вроде
$ /usr/local/gcc-5.2/bin/gcc \
-finput-charset=UTF-8 -fextended-identifiers \
-o circle circle.c