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

Ці з'яўляецца гэта НКА аптымізацыі памылка?

Вось мой код:

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 !

Ці з'яўляецца гэта памылка НКУ? Хто-небудзь калі-небудзь сутыкаліся з аналагічнай памылкай?

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

3
Вы можаце ёсць памылка ў вашым «рабіць нешта» код у Func які громячы які тэлефанаваў PTR
дададзена аўтар Paul R, крыніца
Можа быць, гэта памылка кампілятара, але, перш чым пачаць пошук яго, запусціць праграму пад Valgrind, і пераканайцеся, што няма ніякіх праблем доступу да памяці. Можа быць, у вас ёсць карупцыя стэка недзе.
дададзена аўтар BЈовић, крыніца
Гэта 99,999% памылка ў кодзе. Калі ласка, пост больш кода і рэальнае выкарыстанне + выхад выканання.
дададзена аўтар Kiril Kirov, крыніца
Вы можаце вырабіць працаздольны прыклад, які прайгравае памылку? Код Вы адправілі ніколі не выканаць праблемную лінію, так што немагчыма адгадаць, што можа быць не так з рэальным кодам.
дададзена аўтар Mike Seymour, крыніца
Трэцяе правіла праграмавання: «Заўсёды падазраю, што памылка ў вашым кодзе, а не хто-небудзь яшчэ ці кампілятар»
дададзена аўтар Mitch Wheat, крыніца
А Sidenote: шмат памылак у НКУ былі зафіксаваныя з 2005 года Як гэты код павядзе сябе ў новым кампілятарам?
дададзена аўтар Tadeusz A. Kadłubowski, крыніца
Што адбудзецца, калі вы не выклікаеце FUNC ?
дададзена аўтар Michel, крыніца
Тое, што я не атрымліваю, ваш snipet для FUNC заўсёды вяртае True , а частка вы кажаце аварыі павінны быць выкліканыя толькі калі FUNC зваротаў хлусня .
дададзена аўтар wormsparty, крыніца

2 адказы

Незалежна ад памылак кампілятара можа ці не можа быць, калі вы бачыце праблему, апісаную ў кодзе вы ў курсе, то ваш GCC разбіваюцца на любога ўзроўню аптымізацыі.

Праблематыка радок кода ніколі не павінна быць дасягнута на ўсіх.

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

Калі вы падазраяце, што памылка кампілятара, пачніце пісаць прыклад кода, які прайгравае яго.

Калі мы не ведаем, што ваш фактычны код выглядае, гэта немагчыма для нас, каб здагадацца, ці з'яўляецца правільным ці няма паводзіны ССЗ.

1
дададзена
Цалкам верагодна, але калі мы не ведаем, дзе ён знаходзіцца, і што яшчэ можа здарыцца, што немагчыма адгадаць, што правільнае паводзіны павінна быць
дададзена аўтар jalf, крыніца
Я мяркую, што ёсць вяртаць False дзесьці ў //зрабіць нешта ; альтэрнатыва проста занадта страшна.
дададзена аўтар Stephen Canon, крыніца
О, вядома.
дададзена аўтар Stephen Canon, крыніца

Існуе (верагодна) верагоднасць таго, што ў вас ёсць стэк-Паскаральнік ў Func , які перазапіс PTR на стэк выклікае абанента. Пераканайцеся, што любы масіў або структура звяртаецца ў 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 's значэнне, яно будзе выпадковай велічынёй, амаль не Магчымае не будзе 0.
дададзена аўтар iCoder, крыніца