Подтвердить что ты не робот

Летучие семантики в C99

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

struct x {
  int bar;
};

struct x foobar;
...
volatile struct x *foo = &foobar;

Теперь foo фактически является указателем на объект типа:

volatile struct x {
  volatile int x;
};

поскольку volatile применяется ко всем членам структуры. Теперь мой вопрос в том, когда объект содержит указатель на другой объект, как применяется летучесть?

struct x {
  struct y *bar;
};

Будет ли указатель на неустойчивый экземпляр x затем обрабатывать это как:

volatile struct x {
  struct y * volatile bar;
};

или как:

volatile struct x {
  volatile struct y * volatile bar;
};

Я прочитал стандарт C, и это не очень понятно в отношении этого, и я могу легко интерпретировать формулировку несколькими способами.

4b9b3361

Ответ 1

В вашем примере вы  получить volatile указатель, что все, волатильность не распространяется на объект.

Расширение моего ответа volatile - это расслабленный атом, это означает, что доступ является атомарным, но инструкций не будет. Таким образом, вы не можете никоим образом увеличивать или уменьшать изменчивость, поэтому вы не можете использовать volatile pointer для interation, только операции store/load (assigment). То же самое касается int или другого номера, а volatile также не будет работать с float, потому что они обрабатываются в конвейере FPU, а не в CPU. В целом волатильность не слишком полезна, но компиляторы Microsoft автоматически размещают защитные оболочки вокруг летучих, делая их истинными атомными значениями, но это не является частью стандарта.

Ответ 2

Чтение через стандартный здесь, кажется, что указатель изменчив, но не фактическое содержимое самой структуры. Я понял, что из приведенного примера const t * volatile p (внизу ссылки). Однако формулировка расплывчата, но я думаю, что это будет похожий пример:

struct foo {
    int bar;
};

struct foo *volatile x;

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

Кроме того, cdecl действительно устраняет некоторые неопределенности. Например:

cdecl > explain volatile struct x* foo
объявить foo как указатель на volatile struct x

В то время как:

cdecl > explain struct x* volatile foo
объявить foo как volatile указатель на struct x

В одном случае структура нестабильна. В другом - указатель.