Ограничение-Ключевое слово не работает?

Я использую mingw32-gcc со стандартом C99. Я вставил ниже код с несколькими правками из статьи о ключевом слове restrict - http://wr.informatik.uni-hamburg.de/_media/teaching/wintersemester_2013_2014/epc-1314-fasselt-c-keywords-report.pdf. По словам автора, "Result One" и "Result Two" должны быть разными, но когда я запускаю, они одинаковы. Я не получаю никаких предупреждений компилятора. Есть ли какие-то настройки, которые я упускаю?

#include <stdio.h>

void update(int* a, int* b, int* c)
{
    *a += *c;
    *b += *c;
}

void update_restrict(int* a, int* b, int* restrict c)
{
    printf("*c = %d\n",*c);
    *a += *c;
    printf("\n*c = %d - ",*c);
    printf("shouldn't this have stayed the same?\n\n");
    *b += *c;
}

int main()
{
    int a = 1, b = 2;

    update(&a, &b, &a);

    printf("Result One: a, b =  %d, %d\n", a, b);

    a = 1; b = 2; // reset values

    update_restrict(&a, &b, &a);
    printf("Result Two: a, b = %d, %d\n", a, b);
    getchar();
    return 0;
}

person Nathan Schmidt    schedule 28.04.2015    source источник
comment
restrict не должен влиять на ваш вывод. Это только для компилятора, чтобы сделать возможные оптимизации. Результаты могут быть одинаковыми, а могут отличаться.   -  person cshu    schedule 28.04.2015
comment
Я думал, что в update_restrict значение *c останется прежним после изменения *a, поскольку оно загружается только один раз. Я не понимаю, как это не может повлиять на результаты.   -  person Nathan Schmidt    schedule 28.04.2015
comment
Вы не сказали, как вы компилируете (версия компилятора, флаги командной строки и т.д.). Gcc имеет слабую интерпретацию значения ограничения: маркировка одной переменной, по сути, бесполезна с gcc, он только предполагает, что 2 переменные, которые обе ограничивают, не являются псевдонимами. Кроме того, компилятор может очень хорошо встроить функции, что может решить проблему. Используйте __attribute__((noinline,noclone)) для update_restrict, чтобы избежать этого.   -  person Marc Glisse    schedule 28.04.2015
comment
Я использую версию 4.8.1 с -std=c99.   -  person Nathan Schmidt    schedule 28.04.2015
comment
Я добавил __attribute__((noinline,noclone)), но все равно получил те же результаты. Я попробую несколько примеров с несколькими ограничениями.   -  person Nathan Schmidt    schedule 28.04.2015
comment
Обратите внимание, что с gcc 4.8.2 я получаю результат, который вы ищете, когда все три аргумента update_restrict() отмечены ключевым словом restrict. Обратите внимание, что, как упоминает @Griddoor, неопределенное поведение не означает, что симптом проблемы должен возникнуть, а только то, что он может возникнуть.   -  person Michael Burr    schedule 28.04.2015
comment
Если вы не используете какой-либо флаг оптимизации (например, -O3), конечно, компилятор не оптимизирует...   -  person Marc Glisse    schedule 28.04.2015
comment
забыл упомянуть, я тоже использовал -03.   -  person Nathan Schmidt    schedule 28.04.2015


Ответы (1)


Об использовании restrict

Из wikipedia.org:

Если декларация о намерениях не выполняется и доступ к объекту осуществляется с помощью независимого указателя, это приведет к неопределенному поведению.

Эта строка update_restrict(&a, &b, &a); приводит к неопределенному поведению.

Результаты могут быть одинаковыми, а могут и нет.

person Community    schedule 28.04.2015