Правильное размещение модификатора volatile в программе на Си (Visual Studio) - PullRequest
0 голосов
/ 10 декабря 2018

Я знаю, что модификатор volatile много обсуждался.Пожалуйста, не кричи на меня.Я знаю, почему он используется, но я пытаюсь правильно использовать его в моей многопоточной программе на C, использующей Visual Studio 2008 и 2010. Возникли проблемы с этим в Windows 10. Имеет ли значение, где я помещаю модификатор в простом объявлении?Например, оба они успешно скомпилированы, но мне было интересно, есть ли разница в значении для компилятора:

// difference if any between these two?
volatile char _initialized = 0;
char volatile _initialized = 0;

Как насчет более сложного объявления?Учитывая эту структуру:

typedef struct _KEY_HANDLE
{
    ULONG handle;
    void *ptr;
} KEY_HANDLE;
...
// difference if any between these three
volatile KEY_HANDLE * key_handles = NULL;
KEY_HANDLE volatile * key_handles = NULL;
KEY_HANDLE * volatile key_handles = NULL;
...
key_handles = (PVOID) malloc(bufsz);
...

Спасибо.

Ответы [ 2 ]

0 голосов
/ 11 декабря 2018

https://barrgroup.com/Embedded-Systems/How-To/C-Volatile-Keyword

По этой ссылке оба из двух верхних символов одинаковы.

Аналогично, два указателя KEY_HANDLE являются указателями на энергозависимый KEY_HANDLE, а третий указатель является энергозависимым на энергонезависимый HEY_HANDLE.

volatile KEY_HANDLE * key_handles = NULL;  //pointer to a volatile KEY_HANDLE
KEY_HANDLE volatile * key_handles = NULL;  //pointer to a volatile KEY_HANDLE
KEY_HANDLE * volatile key_handles = NULL;  //volatile pointer to a non-volatile KEY_HANDLE
0 голосов
/ 11 декабря 2018

Для базового типа:

volatile unit32_t *number; //The number pointed at is volatile
uint32_t *volatile number; //The pointer is volatile
volatile uint32_t number; //The number is volatile

Для структуры:

volatile struct_t *struct_p; //The members of the struct pointed at are volatile
struct_t *volatile struct_p; //The pointer is volatile
volatile struct_t struct_o; //The members of the struct are volatile

Конечно, их можно комбинировать:

volatile uint32_t *volatile number; //Both the pointer and the number are volatile

Надеюсь, теперь вы видитеобразец того, что делает модификатор volatile в зависимости от позиции.

Я не использовал volatile таким образом:

uint32_t volatile number; //I assume it will mean that the number is volatile
uint32_t volatile *number; //I assume it will mean that the number is volatile

Правило большого пальца заключается в том, что если модификатор volatile находится за * (указатель), он изменяет указатель, а не указанную переменную.

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

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