2010-04-25

クラスのスコープが難しい

もし、クラスのメンバーの宣言の順番を変えたことにより、プログラムの意味が変わる場合、そのコードは、ill-formedである。

typedef int type ;// #1

class C
{
    type x ;// このtypeは、#1の::type
    typedef int type ;// #2
} ;

これを並び替えると、

typedef int type ;// #1

class C
{
    typedef int type ;// #2
    type x ;// このtypeは、#2の、C::type
} ;

したがって、この最初の例は、ill-formedである。

しかし、二つめの例も、メンバーの宣言の順番を並び替えると、ひとつめの例になってしまう。とすると、ill-formedなのだろうか? いや、これは、問題なく動いて欲しい。さもなくば、安全のためには、常に、qualified nameを使わなければならない。

typedef int type ;

class C
{
    typedef int type ;
    C::type x ;// わざわざqualified nameにしなければならない。
} ;

もちろん、規格のsynopsisですら、そんなことはしていない以上、このコードは、問題ないのだと思う。しかし、規格の文面からでは、どうも、なぜwell-formedなのかが、わからない。

どういうことだろう。

規格には、"If reordering member declarations in a class yields an alternate valid program"と書いてある。最初の例は、このルールにより、ill-formedである。とすれば、ふたつめの例を並び替えても、validなprogramにはならないので、二つめの例は、well-formedなのだろうか。しかし、ひとつめの例をill-formedであると決めているのは、ほかならぬ、このルールである。これは、いったいどうしたものなのだろうか。

あるいは、一つめの例は、(2)の、"A name N used in a class S shall refer to the same declaration in its context and when re-evaluated in the completed scope of S."のルールにも抵触しているであろうから、そのため、一つめの例はill-formedであり、二つ目の例は、well-formedなのかもしれない。たぶん、そうなのだろう。

これは、本で説明するには、詳細すぎる。

追記:やはり、3.3.7 Class scope [basic.scope.class]の1, 2, 3の記述で、定義されている。

VCは、再評価や順番替えによってエラーになるべきコードが、警告も出ずに通る。クソだ。

追記2:基本的に、ルールとしては、クラス内の名前は、一貫していなければならない。もし、クラスの宣言を、最後に再評価して、意味が変わってしまった場合、ill-formedである。その次に、宣言の順番を変えて、合法なコードなのに意味が変わっていたら、ill-formedである。

4 comments:

  1. 2) は省略しないで書くと
    A name N used in a class S shall refer to the same declaration in its context and
    A name N used in a class S shall refer to the same declaration when re-evaluated in the completed scope of S.
    となり、
    ふたつめの例 は 2) and の後ろの条件に引っかかる。
    そのため 3) のif文内の条件をクリアしなくてもよいから
    3) の条件をクリアしなくても良いので
    ふたつめの例 は well-formed
    という理屈の筈。

    ReplyDelete
  2. ごめん間違えた。

    ReplyDelete
  3. ふたつめの例 を 並び替えると
    2) の後半の条件を満たせないから
    valid program を yield しない。

    最初の例 は 並び替えると
    2) の後半の条件を満たす
    valid program を yield する。(つまり、ふたつめの例)
    なので、
    最初の例 は ill-formed

    かな。
    かな。

    ReplyDelete
  4. やっぱり違うか。ごめん。

    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.