Назначить энергонезависимую семантику и стандарт C - PullRequest
Купить гитару в Москве
3 голосов
/
volatile int vfoo = 0;
void func()
{
    int bar;
    do
    {
        bar = vfoo;  // L.7
    }while(bar!=1);
    return;
}

Этот код занят-ждет, когда переменная превратится в 1. Если при первом проходе vfoo не установлено значение 1, я застряну внутри.

Этот код компилируется без предупреждения. Что стандарт говорит об этом?

  • vfoo объявлено как volatile. Следовательно, чтение этой переменной должно быть оптимизировано , а не * 1013. *.
  • Однако бар имеет значение , а не volatile. Разрешено ли компилятору оптимизировать запись в этот bar? .ie компилятор будет делать доступ на чтение к vfoo, и ему разрешено отбрасывать это значение, а не присваивать его bar (на L.7).
  • Если это особый случай, когдаСтандарту есть, что сказать, не могли бы вы включить оговорку и истолковать речь адвоката по стандарту?

Ответы [ 3 ]

3 голосов
/

Что стандарт должен сказать по этому поводу:

5.1.2.3 Выполнение программы

¶2 Доступ к энергозависимому объекту, изменение объекта, изменение файла или вызоввсе функции, выполняющие любую из этих операций, являются побочными эффектами, которые являются изменениями в состоянии среды выполнения. Оценка выражения в целом включает в себя как расчет стоимости, так и инициирование побочных эффектов. Вычисление значения для выражения lvalue включает в себя определение идентичности обозначенного объекта.

¶4 В абстрактной машине все выражения оцениваются в соответствии с семантикой. Реальная реализация не должна оценивать часть выражения, если она может сделать вывод, что его значение не используется и что не возникает никаких побочных эффектов (включая любые, вызванные вызовом функции или обращением к энергозависимому объекту).

¶6 Минимальные требования к соответствующей реализации:

  • Доступ к летучим объектам оценивается строго в соответствии с правилами абстрактной машины.
  • .. .

Вывод, в частности, из should2 должен заключаться в том, что доступ к изменчивому объекту ничем не отличается от вызова типа printf - его нельзя исключить, поскольку он имеет побочный эффект,Представьте, что ваша программа заменена на bar = vfoo; на bar = printf("hello\n");

2 голосов
/

переменная volatile должна читаться при любом доступе. В вашем коде фрагмент не может быть оптимизирован для чтения. Компилятор знает, что побочный эффект может повлиять на bar. Таким образом, условие будет проверено правильно.

https://godbolt.org/z/nFd9BB

0 голосов
/

Тем не менее, bar не является волатильным.

Переменная bar используется для хранения значения. Вас волнует значение, хранящееся в нем, или вас интересует, чтобы эта переменная была точно представлена ​​в соответствии с ABI?

Volatile гарантирует вам последнее. Ваша программа зависит от первого.

Разрешено ли компилятору оптимизировать запись в эту панель?

Конечно. Зачем вам возможно заботиться о том, действительно ли считанное значение было записано в область памяти, выделенную для переменной в стеке?

Все, что вы указали, было то, что считанное значение было проверено как условие выхода:

        bar = ...
    }while(bar!=1);

.ie. Компилятор сделает доступ для чтения к vfoo, и ему разрешено отбрасывать это значение и не назначать его для bar (на L.7).

Конечно, нет!

Компилятору нужно хранить значение, полученное в результате энергозависимого чтения, достаточно времени, чтобы можно было сравнить его с 1. Но не больше времени, поскольку вы никогда не используете bar снова последний.

Может случиться так, что странный процессор в виде флага EQ1 («равно 1») в регистре условий, который устанавливается всякий раз, когда загружается значение, равное 1. Тогда компилятор даже не будет временно хранить считанное значение и только тест условия EQ1.

По вашей гипотезе , что компиляторы могут отбрасывать значения переменных для всех энергонезависимых переменных, энергонезависимых объектовпочти не имеет возможности использовать .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...