IT TIP

C ++ 컴파일러는 언제부터 문자열 리터럴 문자 이스케이프에서 두 개 이상의 16 진수를 고려하기 시작 했습니까?

itqueen 2021. 1. 8. 22:38
반응형

C ++ 컴파일러는 언제부터 문자열 리터럴 문자 이스케이프에서 두 개 이상의 16 진수를 고려하기 시작 했습니까?


\x표기법을 사용하여 이스케이프해야하는 문자를 포함 할 수있는 C ++의 (생성 된) 리터럴 문자열이 있습니다 . 예를 들면 :

char foo[] = "\xABEcho";

그러나 g ++ (중요한 경우 버전 4.1.2)에서는 오류가 발생합니다.

test.cpp:1: error: hex escape sequence out of range

컴파일러는 Ec문자를 선행 16 진수의 일부로 간주하는 것으로 보입니다 (16 진수처럼 보이기 때문에). 4 자리 16 진수는에 맞지 않으므로 char오류가 발생합니다. 넓은 문자열 리터럴의 L"\xABEcho"경우 첫 번째 문자는 U + ABEC이고 그 뒤에 L"ho".

이것은 지난 수십 년 동안 언젠가 변경된 것 같고 나는 결코 눈치 채지 못했습니다. 나는 오래된 C 컴파일러가 뒤에 두 개의 16 진수 만 고려 \x하고 더 이상 보지 않을 것이라고 거의 확신합니다 .

이에 대한 한 가지 해결 방법을 생각할 수 있습니다.

char foo[] = "\xAB""Echo";

그러나 그것은 약간 못 생겼습니다. 그래서 세 가지 질문이 있습니다.

  • 언제 변경 되었습니까?

  • 컴파일러가 와이드 문자열 리터럴에 대해> 2 자리 16 진수 이스케이프 만 허용하지 않는 이유는 무엇입니까?

  • 위의 것보다 덜 어색한 해결 방법이 있습니까?


GCC는 표준을 따릅니다 . # 877 : "각 [...] 16 진수 이스케이프 시퀀스는 이스케이프 시퀀스를 구성 할 수있는 가장 긴 문자 시퀀스입니다."


내 질문에 대한 답을 찾았습니다.

  • C ++는 항상 이런 식이었습니다 (Stroustrup 3 판 확인, 이전에는 없었 음). K & R 1st edition은 전혀 언급하지 않았습니다 \x(당시 사용 가능한 유일한 문자 이스케이프는 8 진수였습니다). K & R 2 판은 다음과 같이 설명합니다.

    '\xhh'
    

    여기서 hh 는 하나 이상의 16 진수 (0 ... 9, a ... f, A ... F)입니다.

    따라서이 동작은 ANSI C 이후로 발생했습니다.

  • 컴파일러가 넓은 문자열 리터럴에 대해 2 자 이상 만 허용하는 것이 가능할 수 있지만, 이는 불필요하게 문법을 복잡하게 만듭니다.

  • 실제로 덜 어색한 해결 방법이 있습니다.

    char foo[] = "\u00ABEcho";
    

    \u탈출 받아 항상 16 진수를.

업데이트 : \u대부분의 ASCII 문자는 (어떤 이유로)를 사용하여 지정할 수 없기 때문에 모든 상황에서 사용이 적용되는 것은 아닙니다 \u. 다음은 GCC의 스 니펫입니다.

/* The standard permits $, @ and ` to be specified as UCNs.  We use
     hex escapes so that this also works with EBCDIC hosts.  */
  else if ((result < 0xa0
            && (result != 0x24 && result != 0x40 && result != 0x60))
           || (result & 0x80000000)
           || (result >= 0xD800 && result <= 0xDFFF))
    {
      cpp_error (pfile, CPP_DL_ERROR,
                 "%.*s is not a valid universal character",
                 (int) (str - base), base);
      result = 1;
    }

\ xnn에도 다음 문자를 지정하여이 문제를 해결했습니다. 안타깝게도 [a..f] 범위에 문자가있는 한 이것을 사용해야합니다. 전의. "\ xnneceg"는 "\ xnn \ x65 \ x63 \ x65g"로 대체됩니다.


나는 C ++이 항상 이런 식이었다고 확신합니다. 어떤 경우에도 CHAR_BIT8보다 클 수 있으며,이 경우 '\xABE'또는 '\xABEc'유효 할 수 있습니다.


이들은 와이드 문자 리터럴입니다.

char foo[] = "\x00ABEcho";

더 나을 수도 있습니다.

여기에 gcc가 아닌 몇 가지 정보가 있지만 여전히 적용되는 것 같습니다.

http://publib.boulder.ibm.com/infocenter/iadthelp/v7r0/index.jsp?topic=/com.ibm.etools.iseries.pgmgd.doc/cpprog624.htm

This link includes the important line:

Specifying \xnn in a wchar_t string literal is equivalent to specifying \x00nn

This may also be helpful.

http://www.gnu.org/s/hello/manual/libc/Extended-Char-Intro.html#Extended-Char-Intro


I also ran into this problem. I found that I could add a space at the end of the second hex digit and then get rid of the space by following the space with a backspace '\b'. Not exactly desirable but it seemed to work.

"Julius C\xE6sar the conqueror of the frana\xE7 \bais"

ReferenceURL : https://stackoverflow.com/questions/5784969/when-did-c-compilers-start-considering-more-than-two-hex-digits-in-string-lite

반응형