C의 이중자와 삼중자

기본적으로는, ISO C에서 일부 문자 집합이 제공하지 않는 글자를 다른 글자의 열로 표현할 수 있도록 하는 기능. 그러나 사실은, C를 꽤 오래 써 왔다는 사람조차도 이 따위 기능의 존재를 몰랐거나, 알더라도 쓸 일이 절대로 없는 매우 무쓸모한 기능이다. 컴파일러 옵션에서 아예 꺼 버리는 것이 정신 건강에 이롭다.

IOCCC에서 종종 나오기도 하지만, 솔직히 그런 코드 짤만한 사람은 대부분 이 물건을 알고 있기 때문에 참신함이 떨어진다는 지적을 받을 가능성이 높다. 그보다 글자 수가 두 배 내지 세 배로 늘어나는데

삼중자

삼중자 대응 문자 삼중자 대응 문자 삼중자 대응 문자
??= # ??/ \ ??' ^
??( [ ??) ] ??! |
??< { ??> } ??- ~

ISO C의 삼중자(trigraph)는 1994년 표준1)에 추가되었으며, 다른 ISO 표준ISO/IEC 646 문자 집합에서 모든 국가에서 지원하지는 않는 문자(ISO/IEC 646 INV)를 다른 방법으로 표현할 수 있게 하려는 목적으로 만들어졌다. 예를 들어 ISO/IEC 646 DE에서는 [] 자리에 ÄÜ가 대신 들어 있기에, a[3] 같은 코드를 aÄ3Ü 처럼 쓰는 불편함이 있는데 이를 a??(3??) 처럼 쓸 수 있게 하려는 것이었다.

…이걸 액면 그대로 믿는다면 ASCII의 8비트 확장이 널리 쓰이던 1994년에 왜 이 기능을 집어 넣고 있는가를 심각하게 고민해 봐야 할 것이다. 그 의도는 좋았지만, 표준에 들어간 시점이 너무 늦었기 때문에 삼중자는 거의 쓸모가 없는 기능으로 전락하고 만다. 게다가 삼중자 치환은 문자열 리터럴과 주석을 포함한 모든 코드 안에서 전처리 직전에 이루어지기 때문에 이런 황당한 버그가 나타날 수도 있다.

// 다음 코드는 실행될까요 말까요????????????????/
printf("우왕ㅋ굳ㅋ\n");

맨 마지막에 (아마 오타로 발생한) ??/\로 바뀌면서 다음 문장이 주석의 일부가 되어 버린다. 안습. (물론 한 줄 주석은 C99에서 새로 추가된 것이다만)

이중자

이중자 대응 문자 이중자 대응 문자 이중자 대응 문자
<: [ :> ] %: #
<% { %> }

ISO C의 이중자(digraph)는 삼중자의 폐해를 줄이면서 삼중자를 대체하려는 시도로 추가2)되었으며, 삼중자와는 달리 문자 단위로 치환되는 게 아니라 토큰 단위로 치환된다. 이를테면 %:%:##와 똑같이 동작하지만, 그건 %:#로 치환되기 때문이 아니라 그냥 (##와 같은 역할을 하는) %:%:라는 토큰이 추가되었기 때문이다. 그러니 문자열 안에서는 바뀌지 않는다.

…그렇다고 이중자가 삼중자를 대체해서 쓰이지는 않고, 그냥 삼중자와 함께 묻혔다. 또한 이중자가 다른 부수효과가 없다고 할 수도 없는게, 이중자 때문에 문법 오류가 나는 경우가 없지는 않다:

#include <string>
 
template <class T>
struct holder {
    T value;
    holder(T value): value(value) {}
};
T<::std::string> stringholder = "Hello?";

이 코드의 경우 T<::std::string>T[:std::string>으로 처리되어 버린다.

1) 대응되는 C99 참조는 ISO/IEC 9899:1999 §5.2.1.1.
2) 대응되는 C99 참조는 ISO/IEC 9899:1999 §6.4.6 문장 3.

도쿠위키DokuWiki-custom(rev 9085d92e02)을 씁니다.
마지막 수정 2011-05-30 18:25 | 외부 편집기