Простенький пример проекта из одного main.cpp файла
Код
// Файл main.cpp
// Тип состояния флага события
typedef volatile enum {
FLAG_STATE_OFF = 0, // Флаг события сброшен
FLAG_STATE_ON = 1 // Флаг события взведён
} Flag_State_t;
// Получить значение флага события по указателю на него
Flag_State_t GetFlagState (const Flag_State_t *Flag_ptr) {return *Flag_ptr;}
// Установить заданное значение флага события по указателю на него
void SetFlagState (Flag_State_t *Flag_ptr,Flag_State_t NewFlsgState) {
*Flag_ptr=NewFlsgState;
};
// Глобальные объекты - флаги событий
Flag_State_t MyFlag1, MyFlag2;
int main () {
SetFlagState (&MyFlag1,FLAG_STATE_ON); // MyFlag1=FLAG_STATE_ON;
MyFlag2=GetFlagState (&MyFlag1); // MyFlag2=MyFlag1;
while(1);
}
Компиляция выдает 2 предупреждения на функции GetFlagState и SetFlagState :
Цитата
warning: #962-D: use of a type with no linkage to declare a function
Если в объявлении типа Flag_State_t убрать volatile - предупреждения исчезнут.
Вопрос: о чём предупреждает Кейл? Чем ему не нравится volatile в определении типа Flag_State_t ?
Более того, если вызовы функций заменить на непосредственное присваивание значений (строки, что закомментированы), то предупреждений тоже не будет. Т.е. наличие volatile играет роль только при наличии функций, аргументы или возвращаемые значения которых имеют тип, определённый с данным спецификатором.
По логике работы программы volatile необходим, т.к. флаги событий взводятся в функциях обработки прерываний, а сбрасываются и проверяются в основном цикле программы. Без него нельзя, иначе компилятор может некорректно оптимизировать код и программа не будет работать, как ей положено.