foo(x[i].key) == 0) { return false; } } "> foo(x[i].key) == 0) { return false; } } "> foo(x[i].key) == 0) { return false; } } " />

これはgccの最適化のバグですか?

ここに私のコードです:

bool func(const MY_STRUCT *const ptr, some_struct *x, int y)
{
    printf("IN: %p\n", ptr);//ok
    for (int i = 0; i < y; ++i) {
        if (ptr->foo(x[i].key) == 0) {
            return false;
        }
    }
    printf("OUT: %p\n", ptr);//ok
    return true;
}

void process(void)
{
    ... ...
    for (i = 0; i < num; ++i) {
        MY_STRUCT *ptr = obj->GetPtr();//success
        printf("BEFORE: %p\n", ptr);//ok
        if (func(ptr, x, y) == false) {
            continue;
        }
        printf("AFTER: %p\n", ptr);// when compile with -O2
        printf("%s", ptr->data);//*** segment fault here ***
    }
}

出力:

BEFORE: 0x0612d3fa
IN: 0x0612d3fa
OUT: 0x0612d3fa
AFTER: 
segment fault

上記のコードを-O0でコンパイルすると、すべて正常に動作します。 しかし、-O2でコンパイルすると、 func 関数が呼び出された後、 ptr NULL になります!

これはgccバグですか?誰もこれまでに同様のバグに遭遇しましたか?

My gcc version is: gcc version 3.4.5 20051201 (Red Hat 3.4.5-2)

3
呼び出し元の ptr を破棄している func の "do something"コードにバグがある可能性があります。
追加された 著者 Paul R,
コンパイラのバグかもしれませんが、それを探し始める前にvalgrindの下でプログラムを実行し、メモリアクセスの問題がないことを確認してください。スタックの破損がどこかにあるかもしれません。
追加された 著者 BЈовић,
それはあなたのコードで99.999%のバグです。より多くのコードと実使用+実行結果を投稿してください。
追加された 著者 Kiril Kirov,
エラーを再現する実行可能な例を作成できますか?投稿したコードは問題のある行を決して実行しないので、実際のコードに何が間違っているのかを推測することは不可能です。
追加された 著者 Mike Seymour,
プログラミングの第3のルール: "バグはあなたのコードではなく、他の人やコンパイラではないといつも思う"
追加された 著者 Mitch Wheat,
sidenote:2005年以降、GCCの多くのバグが修正されました。このコードは、より新しいコンパイラでどのように動作しますか?
追加された 著者 Tadeusz A. Kadłubowski,
func を呼び出さないとどうなりますか?
追加された 著者 Michel,
なぜなら、 func のスニペットは常に true を返し、 func false
追加された 著者 wormsparty,

2 答え

コンパイラのバグに関係なく、記述したコードに記述されている問題がある場合、GCCはすべての最適化レベルで壊れます。

問題のあるコード行には決して到達するべきではありません。

func always returns true, and if it returns true, the last part of the loop body is skipped.

コンパイラのバグが疑われる場合は、まずそれを再現するコードサンプルを作成します。

あなたの実際のコードがどのようなものかわからないときは、GCCの動作が正しいかどうかを推測することは不可能です。

1
追加された
確かにそうかもしれませんが、それがどこにあるのかわからなくて、何が起こるかわからない場合は、正しい行動がどんなものであるべきかを推測することは不可能です
追加された 著者 jalf,
//何かを実行するのどこかに return false があると仮定します。代わりに単に恐ろしいです。
追加された 著者 Stephen Canon,
ああ、絶対に。
追加された 著者 Stephen Canon,

呼び出し元のスタックの ptr を上書きしている func にスタックスマーチャがある可能性があります(可能性があります)。 func の配列や構造体へのアクセスが境界内に残っていることを確認してください。 gcc 3.xの私の酸っぱい思い出のためでなければ、これは実際に何が起こっているのかはほぼ確実だと言います。それでも、これが最も可能性の高い説明です。

あなたのコードがあなたの質問に本当に投稿されている場合は、 その点に疑念の恩恵を与えて、はい、これはコンパイラのバグかもしれません:

    printf("BEFORE: %p\n", ptr);//ok
    if (func(ptr, x, y)) {
        continue;
    }
    printf("AFTER: %p\n", ptr);// when compile with -O2

ptr is passed by value to func, so it's value in the calling function should not change, regardless of what happens within func.

しかし、あなたは真に古代のコンパイラを使用しています。このバグを報告したとしても、それは何も起こりません。これを引き起こした原因は gcc で長らく変わってしまっている可能性が非常に高いです。より新しいバージョンまたは別のコンパイラを試してください。

1
追加された
ありがとう。私は後でgcc4でコンパイルし、結果を投稿しようとします。変わったことは、 ptr は常に NULL です。私は、 func にあるものが ptr の値を書き換えると、ランダムな値になります。
追加された 著者 iCoder,