5

I heard that it is possible to use Unicode variable names using the -fextended-identifiers flag in GCC. So I made a test program in C++, but it does not compile.

#include <iostream>
#include <string>

#define ¬ !
#define ≠ !=
#define « <<
#define » >>

/* uniq: remove duplicate lines from stdin */
int main() {
    std::string s;
    std::string t = "";
    while (cin » s) {
        if (s ≠ t)
            cout « s;
        t = s;
    }
    return 0;
}

I get these errors:

g++ -fextended-identifiers -g3 -o a main.cpp
main.cpp:10:3: error: stray ‘\342’ in program
   if (s ≠ t)
   ^
main.cpp:10:3: error: stray ‘\211’ in program
main.cpp:10:3: error: stray ‘\240’ in program
main.cpp:11:4: error: stray ‘\302’ in program
    cout « s;
    ^
main.cpp:11:4: error: stray ‘\253’ in program

What is going on? Aren't these macro names supposed to work with -fextended-identifiers?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
wefwefa3
  • 3,872
  • 2
  • 29
  • 51
  • Does your version of g++ not include the "error: macro names must be identifiers" diagnostic before it gets to the "stray '\...' in program" errors? –  Sep 26 '15 at 16:09
  • "Ranges of characters disallowed initially [charname.disallowed] 0300-036F, 1DC0-1DFF, 20D0-20FF, FE20-FE2F" – Ben Voigt Sep 26 '15 at 16:18
  • @Lightness: not a dupe, that question asked about usage of characters from the basic set, these characters are definitely extended. – Ben Voigt Sep 26 '15 at 16:20
  • universal-character-names are sequences of `\uXXXX` and `\UXXXXXXXX`. These would be allowed by `-fextended-identifiers`. But what you gave are the characters directly. – Johannes Schaub - litb Sep 26 '15 at 16:21
  • @JohannesSchaub-litb: Would be allowed, provided that they meet the requirements of E.1 and E.2 – Ben Voigt Sep 26 '15 at 16:22
  • @JohannesSchaub-litb: Giving the characters directly is not prohibited. "Any source file character not in the basic source character set (2.3) is replaced by the universal-character-name that designates that character." (section 2.2) – Ben Voigt Sep 26 '15 at 16:25
  • @BenVoigt true, but the GCC option he uses does not promise to accept the corresponding direct encoding. – Johannes Schaub - litb Sep 26 '15 at 16:26
  • @JohannesSchaub-litb: Indeed, it is intended to but not yet implemented: https://gcc.gnu.org/wiki/FAQ#utf8_identifiers – Ben Voigt Sep 26 '15 at 16:28
  • @Lightness: found the real duplicate – Ben Voigt Sep 26 '15 at 16:31

2 Answers2

5

G++ doesn't support Unicode characters in the source yet:

Notably, the errors generated by your program are for the individual octets of the UTF-8 encoding, not for the Unicode character they represent. is being seen as three bytes: \342\211\240 and « as two: \302\253.

Ben Voigt
  • 277,958
  • 43
  • 419
  • 720
  • 1
    ***U+2260*** ([NOT EQUAL TO](https://www.utf8-chartable.de/unicode-utf8-table.pl?start=8704&number=128). UTF-8 342 211 240 (octal), 0xE2 0x89 0xA0 (hexadecimal)) and ***U+00AB*** ([LEFT-POINTING DOUBLE ANGLE QUOTATION MARK](https://www.utf8-chartable.de/unicode-utf8-table.pl?start=128). UTF-8 302 253 (octal), 0xC2 0xAB (hexadecimal)), respectively. – Peter Mortensen May 02 '23 at 18:53
4

The C++ Standard requires (section 2.10):

An identifier is an arbitrarily long sequence of letters and digits. Each universal-character-name in an identifier shall designate a character whose encoding in ISO 10646 falls into one of the ranges specified in E.1. The initial element shall not be a universal-character-name designating a character whose encoding falls into one of the ranges specified in E.2. Upper- and lower-case letters are different. All characters are significant.

And E.1:

Ranges of characters allowed [charname.allowed]

  • 00A8, 00AA, 00AD, 00AF, 00B2-00B5, 00B7-00BA, 00BC-00BE, 00C0-00D6, 00D8-00F6, 00F8-00FF

  • 0100-167F, 1681-180D, 180F-1FFF

  • 200B-200D, 202A-202E, 203F-2040, 2054, 2060-206F

  • 2070-218F, 2460-24FF, 2776-2793, 2C00-2DFF, 2E80-2FFF

  • 3004-3007, 3021-302F, 3031-303F

  • 3040-D7FF

  • F900-FD3D, FD40-FDCF, FDF0-FE44, FE47-FFFD

  • 10000-1FFFD, 20000-2FFFD, 30000-3FFFD, 40000-4FFFD, 50000-5FFFD, 60000-6FFFD, 70000-7FFFD, 80000-8FFFD, 90000-9FFFD, A0000-AFFFD, B0000-BFFFD, C0000-CFFFD, D0000-DFFFD, E0000-EFFFD 0300-036F, 1DC0-1DFF, 20D0-20FF, FE20-FE2F

Your angle brackets are 0x300A and 0x300B, which are not included. Not equal is 0x2260, also disallowed.

Community
  • 1
  • 1
Ben Voigt
  • 277,958
  • 43
  • 419
  • 720