1

作業中のいくつかのC++テンプレートで、GCDを使用して計算を高速化しています。私はすでにいくつかの関数でそれを正常に実行しましたが、今はそれをメンバー関数で機能させようとしていますが、この奇妙なスコープの問題に遭遇しました。コードは次のようになります。

inline void op::factorOutGaussian(const double *x, const complex *y)  
{  
    op a = *this;  
    NSInteger modes = op::modes;  
    NSInteger modes2 = modes*modes;  
    NSInteger *m = op::m;  

    dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

    void (^block)(size_t) = ^(size_t i) {
        NSInteger mi = m[i];
        if (mi == 0) {
            for (NSInteger j = 0; j < modes; j++) {
                this->_a1[i] += a._b1[i*modes+j] * x[j];
                for (NSInteger k = 0; k < modes; k++) {
                    this->_a1[i] += a._c1p[i*modes2+j*modes+k] * x[j] * x[k]
                    + a._c1m[i*modes2+j*modes+k] * y[j*modes+k];
                }
            }
        }

    //A bunch more loops like the one above follow.  You get the idea.

    };
    dispatch_apply(modes, globalQueue, block);

    this->symmetrize();
}

たとえば、a._c1m [ imodes2 + jmodes + k]のような配列要素にアクセスしているときにスコープの問題が発生する可能性があることを理解しています(つまり、そこにいくつかのポインタをスローする必要があるかもしれません)が、ここにあります実際の問題:たとえば、miやループインデックスjとkのようなNSIntegerを宣言すると、コンパイラは次のような大量のエラーを表示します。

'NSInteger op::mi'は'classop'の静的メンバーではありません

これは、このメンバー関数でのみ発生しました。フレンド関数にほぼ同じ手法を実装し(ブロックのスコープ内で同じNSInteger宣言を使用)、問題なく機能しました。

私が考えることができた唯一の修正は、ブロック外のすべてのループ変数をポインターとして宣言し、ブロックのスコープ内でそれらを逆参照することですが、これは一種のハックだと思います。誰かがここで何が起こっているのか知っていますか?

よろしくお願いします!

4

1 に答える 1

1

これは Apples gcc のコンパイラのバグのようです。静的であっても、C++ メンバー関数内で独自の変数を持つブロック リテラルを作成することはできません。したがって、今のところ、このコードをfriend関数に移動して、バグを Apple に報告する必要があります。

于 2010-09-09T19:14:42.780 に答える