Ключевое слово volatile
предназначено для применения к объектам, представляющим хранилище, а не к функциям.Возвращать volatile int
из функции не имеет особого смысла.Возвращаемое значение функции не будет оптимизировано (с возможным исключением встроенных функций, но это совсем другой случай ...), и никакой внешний субъект не будет его модифицировать.Когда функция возвращается, она передает копию возвращаемого значения вызывающей функции.Копия volatile
объекта не является самой volatile
.Следовательно, попытка вернуть volatile int
приведет к копии, приведя ее к энергонезависимой int
, которая вызывает сообщения вашего компилятора.Возвращение volatile int*
может быть полезно, но не volatile int
.
Передача объекта по значению в функцию делает копию объекта, таким образом, использование volatile int
в качестве параметра функции обязательно включаетпреобразование, которое игнорирует классификатор.Передача volatile по адресу вполне разумна, но не по значению.
Согласно спецификации C поведение volatile
полностью зависит от реализации, поэтому YMMV.
Используете ли выvolatile
таким образом попытаться победить какую-то оптимизацию компилятора?Если это так, то, вероятно, есть лучший способ сделать это.
Редактировать: Принимая во внимание обновления вашего вопроса, кажется, что вы можете подойти к этому по-другому,Если вы пытаетесь победить оптимизацию компилятора, почему бы не воспользоваться прямым подходом и просто сказать компилятору не оптимизировать некоторые вещи?Вы можете использовать #pragma GCC optimize
или __attribute__((optimize))
, чтобы задать конкретные параметры оптимизации для функции.Например, __attribute__((optimize(0)))
должен отключить все оптимизации для данной функции.Таким образом, вы можете сохранить свои типы данных энергонезависимыми и избежать проблем с типами, которые у вас возникают.Если отключить все оптимизации слишком много, вы также можете включить или отключить отдельные параметры оптимизации с помощью этого атрибута / прагмы.
Редактировать: Мне удалось скомпилировать следующий код без каких-либопредупреждения или ошибки:
static int functionTwo(int *number) {
return *number + 1;
}
typedef union {
int i;
volatile int v;
} fancy_int;
int main(void) {
fancy_int count;
count.v = 10;
count.v = functionTwo(&count.i);
return 0;
}
Эта "техника" hack , вероятно, имеет какие-то странные побочные эффекты, поэтому тщательно протестируйте ее перед производственным использованием.Скорее всего, ничем не отличается от непосредственного приведения адреса к (int*)
, но он не вызывает никаких предупреждений.