0

OK、コードを拡張する必要がありますが、ここには非常に複雑なものがあります:

((Traces.Last=new SymbolSequence::Node)->Prev=(Discard.First=Processing1)->Prev)->Next=Traces.Last;

これらの割り当てをステートメントに分割する必要がありますが、この順序がわかりません。ここで括弧の順序が私を混乱させています。それは数学のようなものですか、それともコンパイラが彼が望むことをするのですか?

どうもありがとう。

4

3 に答える 3

8

コードはおそらく

Traces.Last = new SymbolSequence::Node;
Discard.First = Processing1;
Traces.Last->Prev = Discard.First->Prev;
Traces.Last->Prev->Next = Traces.Last;

ただし、これは Traces.Last にアクセスし、シーケンス ポイントを介さずに設定するため、実際の結果は未定義です。コンパイラが次のようなものを生成する可能性は十分にあります。

temp = Traces.Last;
Traces.Last = new SymbolSequence::Node;
Discard.First = Processing1;
Traces.Last->Prev = Discard.First->Prev;
Traces.Last->Prev->Next = temp;

そして、元のプログラマーがそのようなことを意図していたこと。

于 2013-08-13T17:52:40.367 に答える
2

私はあなたの痛みを理解しています。全世界が 1 行のコードに依存しているかのようにコーディングする開発者は、ガールフレンドの前で濡れた麺で叩かれるべきです。

そのようなコードをリファクタリングするときは、一度に 1 つずつ開始することが常に役に立ちます。そして、あなたが行くようにテストします。

最も内側の括弧グループにある小さな式を取り出し、それをリファクタリングします。おそらく、それを変数に割り当てることによって。すべてのコードは異なるため、できることを行います。これにより、その大きなコード行が少しずつ縮小されます。式がどんどん小さくなるまで、それを続けます。また、コードのグループ化を物理的に確認し、評価の順序を収集するのに役立つように、演算子の間に空白を入れることも役立ちます。

元のコードを考えると:

((Traces.Last=new SymbolSequence::Node)->Prev=(Discard.First=Processing1)->Prev)->Next=Traces.Last;

これを分割します:

Traces.Last = new SymbolSequence::Node
((Traces.Last)->Prev = (Discard.First = Processing1)->Prev)->Next = Traces.Last;

次に、別の内部割り当てに取り組みます。

Traces.Last = new SymbolSequence::Node
Discard.First = Processing1
((Traces.Last)->Prev = (Discard.First)->Prev)->Next = Traces.Last;

次に、次の最も内側の割り当てに取り組みます

Traces.Last = new SymbolSequence::Node
Discard.First = Processing1
(Traces.Last)->Prev = (Discard.First)->Prev
( (Traces.Last)->Prev )->Next = Traces.Last;

それが役立つことを願っています。

于 2013-08-13T17:55:27.057 に答える
0

コメントで説明されている未定義の動作を超えて、以下は による AST 表現clang++です。AST は、解析された演算子の優先順位を示します。

満たすためにいくつかのタイプであなたの例をブートストラップする必要がありましたclang++:

struct SymbolSequence
{
    struct Node
    {
        Node *First;
        Node *Last;
        Node *Prev;
        Node *Next;
    };
};

void foo()
{
    SymbolSequence::Node *Processing1;
    SymbolSequence::Node Traces;
    SymbolSequence::Node Discard;
    ((Traces.Last=new SymbolSequence::Node)->Prev=(Discard.First=Processing1)->Prev)->Next=Traces.Last;
}

AST:

void foo() (CompoundStmt 0x308b6e0 <go.cpp:14:1, line:19:1>
  (DeclStmt 0x3088dc8 <line:15:5, col:38>
    (0x3088d70 "SymbolSequence::Node *Processing1"))
  (DeclStmt 0x30891d8 <line:16:5, col:32>
    (0x3088e40 "SymbolSequence::Node Traces =
      (CXXConstructExpr 0x30891a8 <col:26> 'struct SymbolSequence::Node':'struct SymbolSequence::Node''void (void)')"))
  (DeclStmt 0x30892d8 <line:17:5, col:33>
    (0x3089250 "SymbolSequence::Node Discard =
      (CXXConstructExpr 0x30892a8 <col:26> 'struct SymbolSequence::Node':'struct SymbolSequence::Node''void (void)')"))
  (BinaryOperator 0x308b6b8 <line:18:5, col:99> 'struct SymbolSequence::Node *' lvalue '='
    (MemberExpr 0x308b618 <col:5, col:87> 'struct SymbolSequence::Node *' lvalue ->Next 0x3088b60
      (ImplicitCastExpr 0x308b600 <col:5, col:84> 'struct SymbolSequence::Node *' <LValueToRValue>
        (ParenExpr 0x308b5e0 <col:5, col:84> 'struct SymbolSequence::Node *' lvalue
          (BinaryOperator 0x308b5b8 <col:6, col:80> 'struct SymbolSequence::Node *' lvalue '='
            (MemberExpr 0x308b448 <col:6, col:46> 'struct SymbolSequence::Node *' lvalue ->Prev 0x3088b00
              (ImplicitCastExpr 0x308b430 <col:6, col:43> 'struct SymbolSequence::Node *' <LValueToRValue>
                (ParenExpr 0x308b410 <col:6, col:43> 'struct SymbolSequence::Node *' lvalue
                  (BinaryOperator 0x308b3e8 <col:7, col:39> 'struct SymbolSequence::Node *' lvalue '='
                    (MemberExpr 0x3089318 <col:7, col:14> 'struct SymbolSequence::Node *' lvalue .Last 0x3088aa0
                      (DeclRefExpr 0x30892f0 <col:7> 'struct SymbolSequence::Node':'struct SymbolSequence::Node' lvalue Var 0x3088e40 'Traces' 'struct SymbolSequence::Node':'struct SymbolSequence::Node'))
                    (CXXNewExpr 0x308b390 <col:19, col:39> 'struct SymbolSequence::Node *'
                      (CXXConstructExpr 0x308b360 <col:23> 'struct SymbolSequence::Node':'struct SymbolSequence::Node''void (void)'))))))
            (ImplicitCastExpr 0x308b5a0 <col:51, col:80> 'struct SymbolSequence::Node *' <LValueToRValue>
              (MemberExpr 0x308b570 <col:51, col:80> 'struct SymbolSequence::Node *' lvalue ->Prev 0x3088b00
                (ImplicitCastExpr 0x308b558 <col:51, col:77> 'struct SymbolSequence::Node *' <LValueToRValue>
                  (ParenExpr 0x308b538 <col:51, col:77> 'struct SymbolSequence::Node *' lvalue
                    (BinaryOperator 0x308b510 <col:52, col:66> 'struct SymbolSequence::Node *' lvalue '='
                      (MemberExpr 0x308b4a0 <col:52, col:60> 'struct SymbolSequence::Node *' lvalue .First 0x3088a40
                        (DeclRefExpr 0x308b478 <col:52> 'struct SymbolSequence::Node':'struct SymbolSequence::Node' lvalue Var 0x3089250 'Discard' 'struct SymbolSequence::Node':'struct SymbolSequence::Node'))
                      (ImplicitCastExpr 0x308b4f8 <col:66> 'struct SymbolSequence::Node *' <LValueToRValue>
                        (DeclRefExpr 0x308b4d0 <col:66> 'struct SymbolSequence::Node *' lvalue Var 0x3088d70 'Processing1' 'struct SymbolSequence::Node *')))))))))))
    (ImplicitCastExpr 0x308b6a0 <col:92, col:99> 'struct SymbolSequence::Node *' <LValueToRValue>
      (MemberExpr 0x308b670 <col:92, col:99> 'struct SymbolSequence::Node *' lvalue .Last 0x3088aa0
        (DeclRefExpr 0x308b648 <col:92> 'struct SymbolSequence::Node':'struct SymbolSequence::Node' lvalue Var 0x3088e40 'Traces' 'struct SymbolSequence::Node':'struct SymbolSequence::Node')))))
于 2013-08-13T17:56:01.410 に答える