Возможно ли получить 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