Подтвердить что ты не робот

? (и другие символы Unicode) в идентификаторах, недопустимых g++

Я 😞, чтобы найти, что я не могу использовать 😃 как действительный идентификатор с g++ 4.7, даже с включенной опцией -fextended-identifiers:

int main(int argc, const char* argv[])
{
  const char* 😃 = "I'm very happy";
  return 0;
}

main.cpp: 3: 3: ошибка: бродячие '\ 360 в программе
main.cpp: 3: 3: ошибка: блуждание '\ 237 в программе
main.cpp: 3: 3: ошибка: отклонение '\ 230 в программе
main.cpp: 3: 3: ошибка: блуждание '\ 203 в программе

После некоторого поиска в Google я обнаружил, что символы UTF-8 еще не поддерживаются в идентификаторах, но универсальное имя-символ должно работать. Поэтому я конвертирую свой источник в:

int main(int argc, const char* argv[])
{
  const char* \U0001F603 = "I'm very happy";
  return 0;
}

main.cpp: 3: 15: ошибка: универсальный символ \U0001F603 недействителен в идентификаторе

Таким образом, очевидно, что 😃 не является допустимым символом идентификатора. Однако стандарт специально позволяет использовать символы из диапазона 10000-1FFFD в Приложении E.1 и не запрещает его как начальный символ в E.2. Следующее мое усилие состояло в том, чтобы увидеть, работают ли какие-либо другие символы юникода, но никто из них не пытался. Даже не имеющий значения PILE OF POO (💩).

Итак, ради значимых и описательных имен переменных, что дает? Делает ли -fextended-identifiers, как он рекламирует или нет? Поддерживается ли это только в самой последней сборке? И какая поддержка у других компиляторов?

4b9b3361

Ответ 1

Начиная с версии 4.8, gcc не поддерживает символы вне BMP, используемые в качестве идентификаторов. Это кажется ненужным ограничением. Кроме того, gcc поддерживает только очень ограниченный набор символов, описанный в ucnid.tab, основанный на C 99 и C++ 98 (он пока не обновляется до C11 и C++ 11, кажется).

Как описано в руководстве, -fextended-identifiers являются экспериментальными, поэтому у них больше шансов, что они не будут работать, как ожидалось.


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

GCC поддерживает набор символов C11, начиная с 4.9.0 (точнее, svn r204886). Таким образом, OP второй кусок кода с использованием \U0001F603 работает. Я до сих пор не могу получить реальный код, используя 😃 чтобы работать даже с -finput-charset=UTF-8 с GCC 8.2 на https://gcc.godbolt.org (вы можете захотеть следить за этим сообщением об ошибке, предоставленным @DanielWolf).

Между тем обе части кода работают на clang 3.3 без каких-либо опций, кроме -std=C++11.

Ответ 3

Однако стандарт специально позволяет использовать символы из диапазона 10000-1FFFD в Приложении E.1 и не запрещает его как начальный символ в E.2.

Следует иметь в виду, что только потому, что стандарт С++ позволяет (или запрещает) некоторые функции, не обязательно означает, что ваш компилятор поддерживает (или не поддерживает) эту функцию.