Skip to content →

Octal Escape Sequences

object님이 적으시며 좌절하신 코드 문제.

int a = strlen("123");
int b = strlen("123");
int c = strlen("12312");
int d = strlen("123123");
int e = strlen("123123ABC");
int f = strlen("123ABC");

C/C++ 프로그래밍 언어 표준을 뒤지며 나름대로 language lawyer로서의 자부심을 가지고 있었는데, 한 순간에 그러한 생각을 깨뜨린 문제네요. 물론 농담이고요. 이런 것을 프로그래밍 실력과 직접적으로 연결해서 생각하지는 않지만, 프로그래머 만이 가질 수 있는 일종의 취미 정도로 생각해주시면 좋을 것 같습니다.

NoSyu님이 컴파일 결과에 따른 답과 나름대로의 해석을 하셨기에 정답은 나온 셈이지만, 이런 문제는 역시 컴파일러의 구현 뿐만 아니라, 표준 문서를 뒤져보아야 하는 문제겠죠.

제가 가지고 있는 C 표준 문서는 ISO/IEC 9899:1999, 소위 C99라고 불리는 문서입니다.

Character constants에 관한 항목은 6.4.4.4인데요. backslash를 이용한 escape sequence는 크게 4가지로 나뉘고, 그 중의 하나가 octal escape sequence입니다. 논의의 간소함을 위해 여기서는 octal escape sequence와 hexadecimal escape sequence만 보도록 하죠.

octal-digit:
0 1 2 3 4 5 6 7
octal-escape-sequence:
 octal-digit
 octal-digit octal-digit
 octal-digit octal-digit octal-digit
hexadecimal-digit:
0 1 2 3 4 5 6 7 8 9
a b c d e f
A B C D E F
hexadecimal-escape-sequence:
x hexadecimal-digit
hexadecimal-escape-sequence hexadecimal-digit

이러한 문법에 따르면 다음과 같은 사실들을 알 수 있습니다.

1. octal escape sequence에는 각각 8진수를 표현하는데 사용할 수 없는 문자는 파싱 단계에서부터 octal escape sequence의 고려에서 제외됩니다. 즉, 위의 문제에서, "ABC"의 경우, ‘A’, ‘B’, ‘C’는 octal-digit가 아니므로, ""만이 octal-escape-sequence로 파싱되고 결과적으로 { ‘’, ‘A’, ‘B’, ‘C’, ‘’ }로 해석되는 것입니다.

이러한 행동은 C89에서 변화된 것으로 보이는데요. 마찬가지 이유로 “78”의 해석은 { ‘7’, ‘8’ }로 되지만, 예전에는 0 prefix에 따르는 2개의 digit를 해석하는 구현의 책임 (implementation-defined)이었고, “78”은 “100”(078 = 0100)으로 해석되기도 한 모양입니다. C89 이전의 머나먼 옛날의 이야기이니, 현 시대의 컴파일러에서 이러한 동작은 신경 쓰지 않아도 될 것 같습니다.

2. octal-escape-sequence에서는 3개까지의 octal-digit를 허용합니다.

예를 들어, “123”는 어떨까요? octal-digit 3개 까지만 허용하므로 일단 ‘3’은 배제하고 “12” “3”으로 해석되겠네요. 그러면 “12”는?

다시 C99 문서로 돌아가보면,

Each octal or hexadecimal escape sequence is the longest sequence of characters that can constitute the escape sequence.

라는 얘기가 있습니다.

즉, “12”는 { ‘’, ‘1’, ‘2’, ‘’ }나, { ‘1’, ‘2’, ‘’ }로 해석되는 것이 아니라, 가장 긴 매치에 해당하는 { ‘12’, ‘’ }로 해석된다는 것입니다. 사실 octal escape sequence에 대해서 알고 나면, 상식적인 이야기라고 볼 수 있겠습니다.

한편, { ‘1’, ‘2’, ‘’ }을 표현하고 싶다면 어떻게 해야할까요? 이것은 C/C++의 편리한 String Concatenation 문법을 사용하면 됩니다. 즉, “1” “2”라고 하면 되겠죠.

3. octal-escape-sequence에서 ‘’ prefix가 요구되지 않습니다. 이것은 그 동안 제가 몰랐던 중요한 사항 중 하나네요. 즉, ‘12’나 ‘12’나 동등한 의미를 가진다는 것입니다. 아마 그 동안 코드를 보면서 그러한 경우를 봐왔을 텐데 조금 더 세심하게 보지 않았던 것 같네요.

재미있는 문제를 제공해주신 object님, 그리고 assembly까지 확인해주신 NoSyu님께 감사드립니다. 🙂

Published in Programming Language Software Development

2 Comments

  1. 굳이 string concatenation 쓸 필요 없이 “012”이라고 써도 됩니다. 최대 매치가 세 글자까지니까요.

  2. 와, 정말이네요. 거기까지는 생각이 미치지 못했습니다. ^^

답글 남기기

이메일 주소를 발행하지 않을 것입니다. 필수 항목은 *(으)로 표시합니다

이 사이트는 스팸을 줄이는 아키스밋을 사용합니다. 댓글이 어떻게 처리되는지 알아보십시오.