2010-10-04

C++0xの落とし穴を埋める改良

聡明なC++0xプログラマである読者諸君ならば、もう、以下のコードは、C++0xでは、疑いようもなくwell-formedであることを知っているだろう。

// C++03ではill-formed
// C++0xではwell-formed
vector<vector<int>> v ;

従来、連続した>は、>>演算子と、文法上曖昧であるので、かならず>>演算子だと解釈されるようになっていた。C++0xでは、このような場合、演算子と解釈されることはなくなった。もちろん、分かりやすさから言えば、空白文字を挟んだ方が分かりやすいだろう。

vector< vector< int > > v ;

何にしても、このようなちょっとした落とし穴は、初心者を無用に混乱させる。、C++0xでは、このようなちょっとした落とし穴がいくつも塞がれている。

さて、ここまでが前振りで、ここからが本番である。以下のコードは、C99では、ill-formedである。C++03ではundefined behaviorである。C++0xではwell-formedである。ただし、[EOF]は、ソースファイルの終りを表す。実際の文字ではない。

int main()
{

}[EOF]

何故か。C99は、空ではないソースファイルは、必ず改行文字で終わらなければならないと定めているからだ。C++03では、空ではないソースファイルが、改行文字で終わっていない場合は、挙動は未定義と定めているからだ。したがって、上記のコードは、C99やC++03といった、前時代の旧言語では、動かない。

しかし、この仕様は、ユーザーの立場になって考えると、馬鹿げている。ソースファイルの終りが改行でなければならないというのは、ユーザー側からすれば、意味が分からない。ユーザー側からすれば、ソースファイルはそこで終わっているのだから。C++0xでは、このような馬鹿げた制限を取り払った。C++0xでは、空ではないソースファイルが、改行文字で終わっていない場合は、改行文字が補われると定めている。したがって、上記のコードは、C++0xという最高にクールな新言語では、well-formedである。

実は、このC++0xの制限緩和は、実に最近の変更である。いつドラフトに入ったのかというと、FCDからである。何と、今年に入ってからの変更だ。

ちなみに、この制限に関する文面は、
C99(TC3)の5.1.1.2 Translation phases paragraph 1.2
C++03の2.1 Phases of translation paragraph 1.2
C++の最新ドラフトN3126の2.2 Phases of translation paragraph 1.2
に書いてある。

2 comments:

  1. POSIX 的にはテキストファイルは改行で終わることになっています。
    ・テキストは行の集合である
    ・行は改行で終わる
    という理屈だそうです。
    これが制約の由来でしょう。
    言語の制約としては無意味ですが、 C の制定当時はツール類との協調を考えてそうしたのかなと想像します。

    ReplyDelete
  2. POSIX由来ですか。
    テキストは行の集合という前提すら、現代人である私からすると、もう理解できませんね。

    ReplyDelete

You can use some HTML elements, such as <b>, <i>, <a>, also, some characters need to be entity referenced such as <, > and & Your comment may need to be confirmed by blog author. Your comment will be published under GFDL 1.3 or later license with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.