Unicode Identifiers and Source Code in C++11?

后端 未结 5 1180
难免孤独
难免孤独 2020-11-30 08:48

I find in the new C++ Standard

2.11 Identifiers                  [lex.name]
identifier:
    identifier-nondigit
    identifier identifier-nondigit
    identi         


        
相关标签:
5条回答
  • 2020-11-30 09:32

    I think the intent is to allow Unicode characters in identifiers, such as:

    long pöjk;
    ostream* å;
    
    0 讨论(0)
  • 2020-11-30 09:45

    Is the new standard more open w.r.t to Unicode?

    With respect to allowing universal character names in identifiers the answer is no; UCNs were allowed in identifiers back in C99 and C++98. However compilers did not implement that particular requirement until recently. Clang 3.3 I think introduces support for this and GCC has had an experimental feature for this for some time. Herb Sutter also mentioned during his Build 2013 talk "The Future of C++" that this feature would also be coming to VC++ at some point. (Although IIRC Herb refers to it as a C++11 feature; it is in fact a C++98 feature.)

    It's not expected that identifiers will be written using UCNs. Instead the expected behavior is to write the desired character using the source encoding. E.g., source will look like:

    long pörk;
    

    not:

    long p\u00F6rk;
    

    However UCNs are also useful for another purpose; Compilers are not all required to accept the same source encodings, but modern compilers all support some encoding scheme where at least the basic source characters have the same encoding (that is, modern compilers all support some ASCII compatible encoding).

    UCNs allow you to write source code with only the basic characters and yet still name extended characters. This is useful in, for example, writing a string literal "°" in source code that will be compiled both as CP1252 and as UTF-8:

    char const *degree_sign = "\u00b0";
    

    This string literal is encoded into the appropriate execution encoding on multiple compilers, even when the source encodings differ, as long as the compilers at least share the same encoding for basic characters.

    Can (portable) source code be in any unicode encoding, like UTF-8, UTF-16 or any (how-ever-defined) codepage?

    It's not required by the standard, but most compilers will accept UTF-8 source. Clang supports only UTF-8 source (although it has some compatibility for non-UTF-8 data in character and string literals), gcc allows the source encoding to be specified and includes support for UTF-8, and VC++ will guess at the encoding and can be made to guess UTF-8.

    (Update: VS2015 now provides an option to force the source and execution character sets to be UTF-8.)

    Can I write an identifier with \u1234 in it myfu\u1234ntion (for whatever purpose)

    Yes, the specification mandates this, although as I said not all compilers implement this requirement yet.

    Or can i use the "character names" that unicode defines like in the ICU, i.e.

    const auto x = "German Braunb\U{LOWERCASE LETTER A WITH DIARESIS}r."u32;
    

    No, you cannot use Unicode long names.

    or even in an identifier in the source itself? That would be a treat... cough...

    If the compiler supports a source code encoding that contains the extended character you want then that character written literally in the source must be treated exactly the same as the equivalent UCN. So yes, if you use a compiler that supports this requirement of the C++ spec then you may write any character in its source character set directly in the source without bothering with writing UCNs.

    0 讨论(0)
  • 2020-11-30 09:46

    I suggest using clang++ instead of g++. Clang is designed to be highly compatible with GCC (wikipedia-source), so you can most likely just substitute that command.

    I wanted to use Greek symbols in my source code. If code readability is the goal, then it seems reasonable to use (for example) α over alpha. Especially when used in larger mathematical formulas, they can be read more easily in the source code.

    To achieve this, this is a minimal working example:

    > cat /tmp/test.cpp
    #include <iostream>
    
    int main()
    {
        int α = 10;
        std::cout << "α = " << α << std::endl;
        return 0;
    }
    > clang++ /tmp/test.cpp -o /tmp/test
    > /tmp/test 
    α = 10
    
    0 讨论(0)
  • 2020-11-30 09:47

    This article https://www.securecoding.cert.org/confluence/display/seccode/PRE30-C.+Do+not+create+a+universal+character+name+through+concatenation works with the idea that int \u0401; is compliant code, though it's based on C99, instead of C++0x.

    0 讨论(0)
  • 2020-11-30 09:49

    Present versions of gcc (up to version 5.2 so far) only support ASCII and in some cases EBCDIC input files. Therefore, unicode characters in identifiers have to be represented using \uXXXX and \UXXXXXXXX escape sequences in ASCII encoded files. While it may be possible to represent unicode characters as ??/uXXXX and ??/UXXXXXXX in EBCDIC encoded input files, I have not tested this. At anyrate, a simple one-line patch to cpp allows direct reading of UTF-8 input provided a recent version of iconv is installed. Details are in

    https://www.raspberrypi.org/forums/viewtopic.php?p=802657

    and may be summarized by the patch

    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;
    
    0 讨论(0)
提交回复
热议问题