реклама на сайте
подробности

 
 
> Warning: #962-D: use of a type with no linkage to declare a function, О чем предупреждает Кейл? Что ему не нравится?
Professor Chaos
сообщение Aug 5 2018, 19:53
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 60
Регистрация: 25-08-17
Пользователь №: 98 970



Простенький пример проекта из одного 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 необходим, т.к. флаги событий взводятся в функциях обработки прерываний, а сбрасываются и проверяются в основном цикле программы. Без него нельзя, иначе компилятор может некорректно оптимизировать код и программа не будет работать, как ей положено.
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
Forger
сообщение Aug 5 2018, 21:09
Сообщение #2


Профессионал
*****

Группа: Свой
Сообщений: 1 215
Регистрация: 22-02-05
Пользователь №: 2 831



Цитата(Professor Chaos @ Aug 5 2018, 22:53) *
Если в объявлении типа Flag_State_t убрать volatile - предупреждения исчезнут.


Все правильно ругается компилятор, ведь typedef volatile можно применить лишь к типам данных: переменные, структуры и классы, а enum к ним не относится.
По сути enum - это что-то вроде #define, "область деятельности" препроцессора, но не самого компилятора как такового. Это если грубо.
По сути volatile - это некое "указание" компилятору что можно делать, а что нет с некоторым объектом данных или объектом указанного типа данных (например: typedef volatile struct).



От себя добавлю: лучше использовать volatile непосредственно при объявлении/создании объекта (переменной), а не вставлять его при объявлении типа данных.
Это позволяет дать возможность компилятору оптимизировать те куски кода, где это действительно нужно, а точнее - только с теми объектами, которые явно указаны, что они volatile.
В противном случае этот typedef с "внедренным" volatile может оказаться в коде там, где volitile окажется даже вредным. Явно это не увидите.

"В довесок": лучше вообще избегать глобальных переменных (поверьте, это вполне реально), тогда и volatile вообще не будет нужен sm.gif

ps Принято указывать версию компилятора и версию самой среды. Хотя в данном случае это не важно, т.к. речь про неправильное применение компилятора как такового.


--------------------
Кругозор некоторых людей - круг с нулевым радиусом. Они называют его "точкой зрения".
Go to the top of the page
 
+Quote Post
Professor Chaos
сообщение Aug 6 2018, 18:31
Сообщение #3


Участник
*

Группа: Участник
Сообщений: 60
Регистрация: 25-08-17
Пользователь №: 98 970



Цитата(Forger @ Aug 6 2018, 00:09) *
От себя добавлю: лучше использовать volatile непосредственно при объявлении/создании объекта (переменной), а не вставлять его при объявлении типа данных.
Это позволяет дать возможность компилятору оптимизировать те куски кода, где это действительно нужно, а точнее - только с теми объектами, которые явно указаны, что они volatile.
В противном случае этот typedef с "внедренным" volatile может оказаться в коде там, где volitile окажется даже вредным. Явно это не увидите.


Спасибо. Действительно так и есть. Если убрать volatile из объявления типа и вставлять его только перед требующими того ОБЪЕКТАМИ, то предупреждения исчезают.



Цитата(Сергей Борщ @ Aug 6 2018, 08:48) *
Ему не нрвится передача volatile enum качестве параметра NewFlsgState и возврат результата в виде volatile enum. Подумайте сами - что означает volatile и как его компилятор должен трактовать в типе параметра и возвращаемого значения? Фактически вам volatile нужен только для MyFlag1 и MyFlag2, поэтому уберите volatile из объявления перечисления и добавьте к объявлению MyFlag1 и MyFlag2. Этим вы заодно дадите компилятору свободу оптимизировать весь остальной код, не связанный с непосредственным обращением к MyFlag1 и MyFlag2.


Тоже согласен.
НО! Вот исправленный код, на который у компилятора нет предупреждений. Обратите внимание, что параметры функций имеют спецификатор volatile. Без них компилятор выдаёт ошибки о несоответствии типов аргументов декларированных и переданных.
Код
// Тип состояния флага события
typedef enum  {
  FLAG_STATE_OFF      = 0,                                    // Флаг события сброшен
  FLAG_STATE_ON       = 1                                        // Флаг события взведён
} Flag_State_t;

// Получить значение флага события по указателю на него
Flag_State_t GetFlagState (volatile Flag_State_t *Flag_ptr) {return *Flag_ptr;}

// Установить заданное значение флага события по указателю на него
void SetFlagState (volatile Flag_State_t *Flag_ptr,Flag_State_t NewFlagState) {
  *Flag_ptr=NewFlagState;
};


// Глобальные объекты - флаги событий
volatile Flag_State_t MyFlag1, MyFlag2;                        


int main (){    
    
  SetFlagState (&MyFlag1,FLAG_STATE_ON);  // MyFlag1=FLAG_STATE_ON;
  MyFlag2=GetFlagState (&MyFlag1);        // MyFlag2=MyFlag1;
  while(1);
}


А если перед типом возвращаемого значения функции GetFlagState добавить volatile, то получим другое предупреждение компилятора: warning: #815-D: type qualifier on return type is meaningless
Это уже как раз то, о чём вы сказали.

Вообще, из 10 ответов только 2 реально по теме. КПД 20%

Для остальных 80%.
Да, код убогий, глупый и никчёмный. Не имеющий никакого практического смысла и применения. Но!!! Задача его была показать суть проблемы, написав при этом минимум строк кода. Чтобы не отвлекать отвечающих СТРОГО ПО-СУЩЕСТВУ ЗАДАННОГО ВОПРОСА на второстепенные детали. И двое из десяти это поняли, и ответили действительно по-существу.
Go to the top of the page
 
+Quote Post
Forger
сообщение Aug 6 2018, 18:37
Сообщение #4


Профессионал
*****

Группа: Свой
Сообщений: 1 215
Регистрация: 22-02-05
Пользователь №: 2 831



Цитата(Professor Chaos @ Aug 6 2018, 21:31) *
Вообще, из 10 ответов только 2 реально по теме. КПД 20%

Так это был тест??? blink.gif


--------------------
Кругозор некоторых людей - круг с нулевым радиусом. Они называют его "точкой зрения".
Go to the top of the page
 
+Quote Post
Professor Chaos
сообщение Aug 6 2018, 19:57
Сообщение #5


Участник
*

Группа: Участник
Сообщений: 60
Регистрация: 25-08-17
Пользователь №: 98 970



Цитата(Forger @ Aug 6 2018, 21:37) *
Так это был тест??? blink.gif

Это был вопрос по-существу. На который нужен был ответ по-существу.
Но количество таких ответов, относительно общего количества ответов, можно расценивать и как результат некоего спонтанного теста biggrin.gif
Go to the top of the page
 
+Quote Post
jcxz
сообщение Aug 7 2018, 06:07
Сообщение #6


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(Professor Chaos @ Aug 6 2018, 22:57) *
Но количество таких ответов, относительно общего количества ответов, можно расценивать и как результат некоего спонтанного теста biggrin.gif

Очередной деятель которому все должны.....
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- Professor Chaos   Warning: #962-D: use of a type with no linkage to declare a function   Aug 5 2018, 19:53
|- - jcxz   Цитата(Forger @ Aug 6 2018, 00:09) ...   Aug 6 2018, 04:48
||- - Forger   Цитата(jcxz @ Aug 6 2018, 07:48) Глобальн...   Aug 6 2018, 05:09
||- - Forger   Цитата(Professor Chaos @ Aug 6 2018, 22:5...   Aug 6 2018, 20:14
|- - Сергей Борщ   QUOTE (Professor Chaos @ Aug 6 2018, 21:3...   Aug 7 2018, 00:27
|- - VladislavS   Цитата(Professor Chaos @ Aug 6 2018, 21:3...   Aug 7 2018, 01:41
|- - Professor Chaos   Цитата(VladislavS @ Aug 7 2018, 04:41) в ...   Aug 7 2018, 02:35
- - VladislavS   Добавлю лишь, что в C++ для объявления типа перечи...   Aug 6 2018, 02:45
|- - Arlleex   Цитата(VladislavS @ Aug 6 2018, 06:45) До...   Aug 6 2018, 04:54
|- - jcxz   Цитата(Arlleex @ Aug 6 2018, 07:54) А мож...   Aug 6 2018, 06:49
|- - Arlleex   Цитата(jcxz @ Aug 6 2018, 10:49) В си++ к...   Aug 6 2018, 07:46
- - Сергей Борщ   QUOTE (Professor Chaos @ Aug 5 2018, 22:5...   Aug 6 2018, 05:48
- - VladislavS   А если ещё вспомнить, что typedef уже заменили на ...   Aug 6 2018, 07:02
|- - Forger   Цитата(VladislavS @ Aug 6 2018, 10:02) А ...   Aug 6 2018, 10:05
- - VladislavS   Форма записи это всё шелуха и вкусовщина. Главное ...   Aug 6 2018, 10:23
- - VladislavS   Не надо нас лечить, лучше принимайте советы к испо...   Aug 7 2018, 02:59
- - VladislavS   Хотел промолчать, но не буду. У человека, который ...   Aug 7 2018, 06:24
|- - Forger   Мне одному кажется, что эта тема к Keil как таково...   Aug 7 2018, 07:31
|- - IgorKossak   Цитата(Forger @ Aug 7 2018, 10:31) Мне од...   Aug 7 2018, 18:44
- - Professor Chaos   Цитата(VladislavS @ Aug 7 2018, 09:24) Хо...   Aug 7 2018, 19:33


Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 9th June 2024 - 20:17
Рейтинг@Mail.ru


Страница сгенерированна за 0.0148 секунд с 7
ELECTRONIX ©2004-2016