Utilizzo dello stack di chiamata come struttura di dati dello stack

2

A volte, uso lo stack delle chiamate come una struttura dati. Uso le variabili locali come elementi nello stack e utilizzo il membro dati di una classe per memorizzare l'elemento superiore. Quando uso questo modello, mi sento come se stessi facendo qualcosa di un po 'cattivo!

Ecco un esempio del modello. Il modello garantisce che le istruzioni break e continue salgano al posto giusto anche in presenza di istruzioni% nidificatewhile, for e switch .

class StatementVisitor final : public ast::Visitor {
public:
  void visitFlow(ast::Statement *body, llvm::BasicBlock *brake, llvm::BasicBlock *continoo) {
    // Store the old blocks in local variables and push the new blocks.
    llvm::BasicBlock *oldBreak = std::exchange(breakBlock, brake);
    llvm::BasicBlock *oldContinue = std::exchange(continueBlock, continoo);
    // Traverse a statement that might be a block that might have some
    // break or continue statements in it.
    body->accept(*this);
    // Pop the top blocks and restore the previous blocks
    continueBlock = oldContinue;
    breakBlock = oldBreak;
  }

  void visit(ast::For &four) override {
    // ...
    visitFlow(four.body.get(), doneBlock, incrBlock);
    // ...
  }

  void visit(ast::Break &) override {
    // ...
    funcBdr.ir.CreateBr(breakBlock);
    // ...
  }
  void visit(ast::Continue &) override {
    // ...
    funcBdr.ir.CreateBr(continueBlock);
    // ...
  }

private:
  // the blocks that continue and break statements should jump to
  // these are on the top of the stack
  llvm::BasicBlock *continueBlock;
  llvm::BasicBlock *breakBlock;
  FuncBuilder funcBdr;
};

Potrei usare std::stack<llvm::BasicBlock *> e alla fine ottengo la stessa quantità di codice. Questo schema probabilmente salva la memoria e alcune allocazioni di heap in std::stack . È così radicato nella mia mente (dopo averlo usato in altri due posti) che penso di usarlo prima di rendermi conto che potrei usare un std::stack .

Dovrei evitare di usare questo modello?

    
posta Kerndog73 21.12.2018 - 07:07
fonte

1 risposta

5

Questo è un modello completamente normale per un visitatore. L'utilizzo dei campi di classe come parte superiore di uno stack che viene inserito e inserito nella catena di chiamata del metodo è una soluzione perfettamente accettabile. È fondamentalmente una soluzione al fatto che non è possibile passare parametri extra a un visitatore generico.

A volte è meglio capirlo come tracciare il contesto di un visitatore. Se si finisce per avere un sacco di stato, potrebbe valere la pena creare un helper per spingere / inserire quei valori tramite RAII dato che si è in C ++. Puoi anche considerare di suddividere il tuo visitatore in più parti in modo da poter passare la parte superiore dello stack come parametro al nuovo oggetto. Potrebbe essere utile se l'immutabilità è una preoccupazione per il tuo codice.

    
risposta data 21.12.2018 - 07:25
fonte

Leggi altre domande sui tag