2017-10-26 20 views
2

以下のコードを参照してください。正しい出力は "10 20 30"ですが、リリースでは "0 0 0"が作成されます。なぜこれが起こるのですか?ラムダでのみ使用されているリリースビルドではローカルスタティック変数が初期化されていません

std::vector<int> inValues = {1, 2, 3}; 
    std::vector<int> outValues(inValues.size()); 

    static const int mag = 10; 

    std::transform(inValues.cbegin(), inValues.cend(), outValues.begin(), 
    [](const auto value){ 
    return value * mag; 
    }); 

    for (const auto value: outValues) 
    std::cout << value << " "; 

変数が関数内のどこにも記述されている場合、またはグローバルスコープで宣言されている場合は、すべて正常に動作します。ラムダの変数をキャプチャする

答えて

2

いえば、http://en.cppreference.com/w/cpp/language/lambda#Explanationは言う:それは自動記憶域期間を持っていない場合

変数が捕獲されることなく使用することができる(すなわち、それはローカル変数ではないか、それが静的またはスレッドですローカル)

変数です。したがって、「静的ローカル」は自動的にキャプチャする必要があります。さらにMicrosoft gives this example of using a local static storage element

void fillVector(vector<int>& v) 
{ 
    // A local static variable. 
    static int nextValue = 1; 

    // The lambda expression that appears in the following call to 
    // the generate function modifies and uses the local static 
    // variable nextValue. 
    generate(v.begin(), v.end(), [] { return nextValue++; }); 
    //WARNING: this is not thread-safe and is shown for illustration only 
} 

あなたの例にはないが、意図したとおりこれは、作業を行います。

これはバグです。で解決されたと報告することができます。ですから、これをバグとして報告することは自由ですが、私はVisual Studio 2017にアップグレードすることをお勧めします。報告することを選択した場合は、ここでバグレポートをリンクすることをお勧めします。

+1

私はあなたを考えた:あなたはstatic修飾子を維持する程度断固としている場合

そうでない場合、あなたはちょうどそう、その値は、コンパイル時に離れて最適化されていない、それを定義した直後magを使用することをふり静的変数を取得する必要はありませんか? – frslm

+0

@frslmあなたは大丈夫です。これはVisual Studioのバグです。イースターエッグを見つけるために+1してください。 –

+1

clangツールセットを使用して構築しようとしましたが、完全に機能します。うん、そのバグ。 –

1

面白いことに、magはコンパイル時に0に設定されているようです。 Visual Studioでは、ラムダ式で実際に使用されていることは認識されていません。

magconst intに変更することができます。関数内で定義した場合はと比べてintstatic constと定義すると得られるメリットはほとんどありません。

static const int mag = 10; 
(void)mag; // (pretend to use mag) 
+0

いいえ、静的なconstはここで偶然によって使用されましたが、それはとにかく良い練習ではありません。関数内の 'mag'を言及すると、コンパイラのバグだけが隠されます。 –

関連する問題