2017-02-05 10 views
1

続きを読む私はVS2015コード解析の出力を見てきましたが、次のように簡略化できる関数でスタック使用率が高いという警告が表示されます。スタックフレームはスコープで割り当てられ、割り当てが解除されていますか?

class base 
{ 
public: 
    virtual void Process(); 
    Buffer[10000]; 
}; 

class derived1 : public base 
{ 
public: 
    void Process(); 
} 

class derived2 : public base 
{ 
public: 
    void Process(); 
} 

void MyFunc(int x) 
{ 
    switch(x) 
    { 
    case 0: 
    { 
     derived1 x; 
     x.Process(); 
    } break; 
    case 1: 
    { 
     derived2 y; 
     y.Process(); 
    } break; 
    } 
} 

この分析では、私がMyFuncに20,000バイトのスタックを使用していることが警告されています。これは、すべてのスタック変数が、関数エントリで割り当てられ、関数出口で割り当て解除され、スコープで構築され、破棄されるためではありませんか?ちょうど興味がありません(しかし、アセンブリの出力を渡り歩くのに十分興味がありません;))related questionここでは私が探している答えはあまりありません。

+1

コンパイラとその最適化によって異なります。これは標準によって直接義務づけられたものではありません。 – Mat

答えて

1

スタックフレームの割り当ては、コンパイラの裁量で行われます。ほとんどのコンパイラは、大きな変数でローカルスコープを分離しようとはしませんが、ほとんどのコンパイラは、既存のスタックフレームを動的に拡張するallocaまたはC99 VLAのような機能を提供します。したがって、建築上の問題は起こりそうにない。純粋に実装の詳細の問題です。

あなたは、このようなアイソレーションを提供するために、コンパイラを奨励するためにラムダ式でローカルスコープを囲むことができます。

​​

はまだ、何も保証されません。

godbolt.orgオンラインコンパイラを使用して、このような例のマシンコードの逆アセンブリを確認できます。このトリックはGCC上で動作するようですが、Clangでは最適化-O1以下でしか動作せず、インテルのコンパイラでは-O0としか動作しません。

関連する問題