C++という言語を詳細に、取りこぼしのないよう解説するのがとても難しい。安易に、規格通りの目次で解説していけば良いのではないかと思ったが、これもまた、問題がある。
たとえばポインタだ。規格通りの目次でいくと、ポインタの宣言、ポインタの参照、ポインタに対する加減算は、別々の場所で説明されることになる。
演算子というものをすべて、expression(式)の章で説明するのは、問題がないと思う。しかし、Additive operators(加減算演算子)の項目で、整数に対する演算と、ポインタに対する演算を説明したものだろうか。ポインタなら、ポインタで、ひとまとめにして説明したい。
あるいは、内容が重複してもいいというのならば、個々に解説したあと、まとめて解説するという方法もある。このように、バラバラに説明されると分かりにくい項目というのは、それほど多くはない。ポインタ、リファレンス、関数等々、これらを総合的に解説する章というものを設けてもいいかもしれない。
さらに、純粋に、規格として定義されている言語仕様を解説すると、人間にとっての自然な文法とは、だいぶ違ったものになる。たとえば、=(イコール記号)だ。
int x = 0 ; // #1 x = 0 ; // #2
このふたつのイコール記号の使い方は、どちらも代入演算子だと考えている人が多いのではないだろうか。じつは違う。まず用語だ。言語的には、代入演算子ではなく、assignment-expression(代入式)という名称がついている。式の中に、さらに式を入れることができるから、このような名称になっているのだ。その代入式の中に、代入演算子が存在する。上のコードで、代入式とは、#2のことである。では、#1は何か。これはinitializer(初期化子)である。宣言文に=記号を使った場合、初期化子となる。見た目が同じだからと言って、同じ文法とは限らないのだ。
initializerの右辺には、assignment-expressionを取ることができる。つまり、0とは、assignment-expressionである。#1のイコール記号は、そもそも、演算子ではない。
しかし、言語学者でない、普通のプログラマが、このコードを見れば、「どっちも代入演算子じゃん」と思うはずである。「うむ、これらは明確に別の文法じゃ。大方、初期化子と代入式とか呼ばれとるもんじゃろうて」とは思わないはずである
どこまで言語仕様に忠実に説明するかというのは、非常に難しい問題だ。果たして、初期化子と代入式の違いまで、説明するべきだろうか。さらに、expression(式)とoperator(演算子)の違いも、説明するべきだろうか。読者はどこまで詳しく解説することを求めているのだろう。
2 comments:
規格書の順番は無視して、説明しやすい順番に変えたほうがいいと思いますよ。実際規格書は、まだ定義していない、後のほうで出てくる用語をばんばん使ってますから、読みにくいです。
例にあるpointerですが、pointerに対する演算はpointerの項目で説明したほうがいいと思いますよ。Additive operatorsの項目でも補足的に触れてもいいかもしれませんが。
Assignment expressionとInitializerの違いは是非説明するべきではないかと思います。Classになるとまた見た目が違ってくる可能性があるわけですし。
Expressionとoperatorも言語要素として別物なので、この違いも説明するべきではないかと思いますね。Expressionの説明をするわけですから。
classを定義する時、初期化と代入はそれぞれコンストラクタとoperator=という別物になるので、
全く別の物だということをむしろ強調したほうが良い気がします。
Post a Comment