Ответ 1
Нет стандартного способа отключения оптимизаций, поэтому, если вам нужно отключить оптимизацию, вы ограничены тем, что может сделать ваша реализация. Не имеет смысла сравнивать два подхода, если вы не найдете компилятор, который поддерживает их обоих.
В любом случае, в GCC,
asm volatile("" : "+r" (datum));
означает, что непроверенный код сборки, предоставленный пользователем, встроен в сборку, сгенерированную GCC. Первый строковый литерал (""
) содержит код сборки для вставки. Он пуст, поэтому на самом деле нет никакого кода, который испускается вообще.
Часть после :
сообщает GCC о влиянии кода сборки. "+r" (datum)
означает, что GCC должен предположить, что код сборки считывает и изменяет datum
. Хотя это не так. Причина этого в том, что любые более ранние вычисления, которые в конечном итоге сохраняют значение в datum
, не могут быть отброшены как ненужные. В то же время сам код сборки не может быть отброшен как ненужный из-за потенциальной модификации datum
. volatile
также отмечает код сборки как код, который нельзя оптимизировать, как описано здесь:
Оптимизаторы GCC иногда отбрасывают операторы
asm
, если они определяют отсутствие выходных переменных. Кроме того, оптимизаторы могут перемещать код из циклов, если они считают, что код всегда будет возвращать тот же результат (т.е. Ни одно из его входных значений не меняется между вызовами). Использование квалификатораvolatile
отключает эти оптимизации. [...]
Кажется, что немного использовать два разных подхода, чтобы предотвратить удаление кода сборки, действительно, но я думаю, что лучше всего быть уверенным.
Ограничение r
означает, что код не заботится обо всем, что регистрирует GCC для использования кода сборки, и здесь документируется:
"г
Регистр-операнд допускается при условии, что он находится в общем регистре.
Модификатор +
означает, что код может читать и записывать в datum
, а здесь описано:
"+
Означает, что этот операнд читается и записывается инструкцией. [...]