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

 
 
> Странное поведение EWAVR 4.21A, Возникновение ошибки при объявлении структуры
Baser
сообщение Feb 28 2008, 21:59
Сообщение #1


Просто Che
*****

Группа: Свой
Сообщений: 1 567
Регистрация: 22-05-07
Из: ExUSSR
Пользователь №: 27 881



Вдруг начала возникать ошибка на пустом месте, когда пытаюсь объявить структуру в одном си файле, объявление extern в хедер файле, а применить эту структуру в третьем си файле:
Код
Error[Pe147]: declaration is incompatible with "struct <unnamed> __near GSM_Rx" (declared at line 27 of "C:\My_Jobs\ C:\My_Jobs\VB1\gsm.c 13

Причем ошибка пропадает, если заменить структуру на отдельные char или передвинуть эти объявления в другие файлы sad.gif

Что это может быть? Час потратил, передвигая структуру с места на место - никакой закономерности не обнаружил, то она есть, то нет wacko.gif

Кому не лень, посмотрите у себя, может на другой версии этого глюка нет?
Обкоцанный (но с ошибкой) проект прилагаю. От машины не зависит: и на работе, и дома одинаково.
Ошибка возникает в файле gsm.c на структуре GSM_Rx
Прикрепленные файлы
Прикрепленный файл  VB1.zip ( 15.88 килобайт ) Кол-во скачиваний: 65
 
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
Baser
сообщение Feb 29 2008, 09:32
Сообщение #2


Просто Che
*****

Группа: Свой
Сообщений: 1 567
Регистрация: 22-05-07
Из: ExUSSR
Пользователь №: 27 881



Цитата(zltigo @ Feb 29 2008, 00:55) *
Это не вдруг sad.gif
Все-таки, предложеный вами typedef - это не решение вопроса, а обходной путь. Через typedef все работает. Я вообще typedef применяю только тогда, когда нужно структуру применить несколько раз. В случае уникальной структуры предпочитаю явные определения. Иначе, для того, чтобы посмотреть на члены структуры, приходится лезть лишний раз в хедер. Зачем мне лишняя вложенность, только ухудшает понимабельность. А в этом конкретном случае я решил свести несколько отдельных char в структуру только исходя из эстетических соображений smile.gif По стандарту Си мой вариант написания совершенно легален.

Цитата(rezident @ Feb 29 2008, 01:12) *
...Пользуйтесь активнее условной компиляцией...
Это дельное замечание, буду применять. Раньше писал небольшие проекты, ограничивался несколькими файлами в проекте: main.c; modules.c; isr.c; memory.c; defines.h - все было без проблем. Сейчас проект побольше. А когда в файле больше нескольких тысяч строк, уже неудобно, решил начать делить проект ещё и по периферии. Вот и возникла по-первости такая каша smile.gif

to All: Спасибо за участие, с вашей помощью разобрался, дело в следующем. ИАР не всегда дозволяет в одном модуле наличие собственно определения переменной и определение её как extern. Примеры:

Это проходит без ошибок:
Код
extern char a;
extern int b[10];
char a;
int b[10];

typedef struct c_t{
    char a;
    int  b;
    } c_t;
extern c_t ccc;
c_t ccc;
extern c_t ccc;


А на явное определение struct или union ругается:
Код
struct {
    char a;
    int  b;
    } ddd;
extern struct {
    char a;
    int  b;
    } ddd;


И я не знаю, правильно это или нет. По моему мнению все должно быть однообразно, а не так sad.gif
Go to the top of the page
 
+Quote Post
zltigo
сообщение Feb 29 2008, 10:02
Сообщение #3


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(Baser @ Feb 29 2008, 12:32) *
Все-таки, предложеный вами typedef - это не решение вопроса, а обходной путь.

Можно и без typedef, это совершенно не принципиально (см. приложение). Но
1. структуры надо описывать просто, однозначно и в одном месте.
2. нет ни одной причины не использовать typedef везде, где это возможно.
Цитата
Иначе, для того, чтобы посмотреть на члены структуры, приходится лезть лишний раз в хедер.

Проблема в том, что просто нужно использовать нормальные текстовые редакторы, как минимум поддерживающие тэги - решает массу проблем со стилем написания и навигацией, а не только с просмотром структур.
Цитата
И я не знаю, правильно это или нет.

Правильно.
Прикрепленные файлы
Прикрепленный файл  gsm_s.rar ( 1.22 килобайт ) Кол-во скачиваний: 59
 


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
Baser
сообщение Feb 29 2008, 12:32
Сообщение #4


Просто Che
*****

Группа: Свой
Сообщений: 1 567
Регистрация: 22-05-07
Из: ExUSSR
Пользователь №: 27 881



Цитата(zltigo @ Feb 29 2008, 12:02) *
... 2. нет ни одной причины не использовать typedef везде, где это возможно.
Ну почему же, или причина которую я привел не причина? smile.gif

Цитата
... нужно использовать нормальные текстовые редакторы...
Дело вкуса и привычки (и главное, лени smile.gif )

Код
struct GSM_Rx_s {
  unsigned char Buf[80];
  unsigned char Start;
  ...
  };
extern struct GSM_Rx_s GSM_Rx;
struct GSM_Rx_s GSM_Rx;

Такое тоже применяю, мне такая форма нравится даже больше, чем typedef

Цитата
Правильно.
А вот если бы вы объяснили почему, или привели ссылку на страницу стандарта - было бы просто замечательно. В таких вещах верить нА слово не привык.
Вот мне все-таки кажется, что компилятор должен был бы ругаться во всех вышеприведенных мною примерах, т.к. объявление в одном модуле переменной и как глобальной и как внешней больше похоже на ошибку.
Go to the top of the page
 
+Quote Post
zltigo
сообщение Feb 29 2008, 12:46
Сообщение #5


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(Baser @ Feb 29 2008, 15:32) *
объявление в одном модуле переменной и как глобальной и как внешней больше похоже на ошибку.

Нет - обычный разумный подход делу, поскольку ругань в таком случае исключает нормальное использование header-ов в файлах, где собственно переменные объявлены. Ни к каким ошибкам это привести не может, поскольку если "снаружи" вдруг еще такая переменная существует, то на это 100% выругается линкер.
Цитата
Ну почему же, или причина которую я привел не причина?

Причина ну никак не относится к использованию или неиспользованию typedef. Или я чего-то совсем не понимаю.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
Baser
сообщение Feb 29 2008, 13:49
Сообщение #6


Просто Che
*****

Группа: Свой
Сообщений: 1 567
Регистрация: 22-05-07
Из: ExUSSR
Пользователь №: 27 881



Цитата(zltigo @ Feb 29 2008, 14:46) *
Причина ну никак не относится к использованию или неиспользованию typedef. Или я чего-то совсем не понимаю.
Да, похоже мы одни и те же слова воспринимаем по-разному. Я имею ввиду след: если стандарт в конкретном случае разрешает не применять typedef и я считаю, что так будет наглядней, то нет никаких причин его использовать. Короче, тоже дело вкуса, спорить не о чем smile.gif

Цитата
Нет - обычный разумный подход делу, поскольку ругань в таком случае исключает нормальное использование header-ов в файлах, где собственно переменные объявлены. Ни к каким ошибкам это привести не может, поскольку если "снаружи" вдруг еще такая переменная существует, то на это 100% выругается линкер.
Со всем этим согласен. Но почему тогда это недопустимо по отношению к структурам, описанным в явном виде:
Код
extern struct {
    char a;
    int  b;
    } ddd;
struct {
    char a;
    int  b;
    } ddd;
Error[Pe147]: declaration is incompatible with "struct <unnamed> __near ddd"

Я не вижу логики в действиях компилятора. Или он начинает и в случае extern выделять память?
Go to the top of the page
 
+Quote Post
zltigo
сообщение Feb 29 2008, 14:25
Сообщение #7


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(Baser @ Feb 29 2008, 16:49) *
Я имею ввиду след: если стандарт в конкретном случае разрешает не применять...
...
Короче, тоже дело вкуса, спорить не о чем smile.gif

Стандарт языка позволяет многое чего не применять, он даже совершенно спокойно позволяет делать массу ошибок smile.gif, но при этом дает некоторые средства для контроля над типами уменьшающие вероятность потенциальных ошибок. Пользоваться или нет - это не "дело вкуса", это показатель уровня владения инструментом. На рояле я тоже могу чего-нибудь настучать одним пальцем - он мне это вполне позволит, только рассуждать о вкусах я при этом не буду smile.gif
Цитата
Я не вижу логики в действиях компилятора. Или он начинает и в случае extern выделять память?

Для начала я не вижу логики в действиях программиста дважды определившего одну и ту-же структуру. Дальнейшие логические построения, рассуждения и толкования должен-ли 'extern' служить решающим указанием компилятору для того, что-бы считать это нагромождение разумным, меня с практической точки зрения совершенно не интересуют. Однако, поведение любого компилятора молча глотающего подобные выражения сочту совершенно неправильным.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
Baser
сообщение Feb 29 2008, 16:06
Сообщение #8


Просто Che
*****

Группа: Свой
Сообщений: 1 567
Регистрация: 22-05-07
Из: ExUSSR
Пользователь №: 27 881



Цитата(zltigo @ Feb 29 2008, 16:25) *
Для начала я не вижу логики в действиях программиста дважды определившего одну и ту-же структуру...
Однако, поведение любого компилятора молча глотающего подобные выражения сочту совершенно неправильным.
Не надо так сразу кипятится smile.gif , я же разобраться хочу, а не просто так по клавишам стучу. Очень часто простейшие мысли в голову почему-то сразу не приходит. Теперь дошло, действительно удобнее только один раз описывать. Но компилятор, ИМХО, мог бы ограничится предупреждением, поскольку структуры идентичны.

Цитата
... но при этом дает некоторые средства для контроля над типами уменьшающие вероятность потенциальных ошибок...
Насчет контроля типов тут много копей сломано. Но я в этом вопросе так и не разобрался. Вот вы говорили:
Цитата
#define и typedef по разному обрабатываются - один препроцессором, а второй компилятором. Компилятор (или дополнительные утилиты типа lint) могут дополнительно заниматься котролем типов, а препроцессор - нет.
Тут хотя случай без #define, но похоже. Чем все-таки будет отличаться обработка структур CCC и DDD? И там и там структура, и там и там ее обрабатывает компилятор:
Код
typedef struct cc {
    char a;
    int  b;
    } ccc_t;
ccc_t CCC;

struct dd {
    char a;
    int  b;
    } DDD;
Кстати, если бы был #define, то после него все равно явное описание типа обрабатывалось бы компилятором.

Вот Сергей Борщ в том обсуждении сказал: "Поэтому надо больше читать тематической литературы. Разница есть."
А я никак не могу найти ту "техническую литературу", где этот вопрос освящен. Например у Кернигана и Ричи (2-е изд) применение typedef никак не связывается с улучшенным (добавочным) контролем типов:
Цитата
Следует подчеркнуть, что объявление typedef не создает объявления нового типа, оно лишь сообщает новое имя уже существующему типу. Никакого нового смысла эти новые имена не несут, они объявляют переменные в точности с теми же свойствами, как если бы те были объявлены напрямую без переименования типа. Фактически typedef аналогичен #define с тем лишь отличием, что при интерпретации компилятором он может справиться с такой текстовой подстановкой, которая не может быть обработана препроцессором...
Помимо просто эстетических соображений, для применения typedef существуют две важные причины. Первая - параметризация программы, связанная с проблемой переносимости...
Вторая причина, побуждающая к применению typedef,- желание сделать более ясным текст программы...

И все... Так где об этом можно почитать? Гуру, дайте ссылку rolleyes.gif
Go to the top of the page
 
+Quote Post
zltigo
сообщение Feb 29 2008, 16:50
Сообщение #9


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(Baser @ Feb 29 2008, 19:06) *
Не надо так сразу кипятится smile.gif

Ооооо! Кипячусь совсем не так smile.gif. В данном случае я совершенно спокоен, не спокоен, я буду, например, тогда, когда мой заказчик потребует не пользоваться typedef smile.gif
Цитата
Чем все-таки будет отличаться обработка структур CCC и DDD? И там и там структура

Две совсем разные вещи! В одном случае это определение структуры а во втором создание структуры во время ее определения - так сказать заплатка для краткости и выразительности. В случае локальной/статической структуры - позволяет с минимальными количеством ударов по клавишам описать и создать локальную структуру. Сам пользуюсь, при этом сам внешний вид при чтении подчеркивает ограниченность применения такой структуры. Попытки описания в таком стиле глобально доступных структур просто банально неудобны, поскольку требуют дважды дублировать описание структуры - при ее создании и при обращении к структуре за пределами объекта компиляции. Посему сетовать на компилятор, который не желает понимать, что добавлением extern Вы хотите не создать структуру, а только ее описать, я совершенно не собираюсь. Кстати, повторю, использование typedef не принципиально (пример приводил).
Цитата
Так где об этом можно почитать? Гуру, дайте ссылку

Наверное, я дурак sad.gif - я много учился на своих, а не на чужих ошибках sad.gif. Посему ссылок у меня нет. Чувство языка есть, писать могу, а ссылок нет smile.gif. Книгу, что-ли написать? smile.gif и ссылаться. Единственно, что меня несколько оправдывает, так это то, что на момент достижения мною приличного уровня программирования Интернета, считайте еще не было sad.gif. Диалап по модему 2400/NONE на LatNet, по знакомству, с возможностью (чудо!) поползать по FTP это уже позже - год 91-92....

P.S.
Кстати, попробовал четыре наиболее используемых мной компилятора, рад сообщить, что мое мнение совпало с мнением их создателей smile.gif.

Сообщение отредактировал zltigo - Feb 29 2008, 19:24


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
Baser
сообщение Feb 29 2008, 21:16
Сообщение #10


Просто Che
*****

Группа: Свой
Сообщений: 1 567
Регистрация: 22-05-07
Из: ExUSSR
Пользователь №: 27 881



Цитата(zltigo @ Feb 29 2008, 18:50) *
Кстати, повторю, использование typedef не принципиально (пример приводил).
Вопрос, вынесенный мною в тему топика, я уже для себя прояснил, спасибо. Просто мне показалось, что вы раньше делали упор на то, что применение typedef при определении структур улучшает именно контроль типов, а не удобство использования структуры. Если я не прав, поправьте меня.

Сейчас у меня в процессе разговора на первый план вышел другой вопрос, который я пытался задать в предыдущем посте, но видимо неудачно. Это тот старый вопрос с #define. Вот он еще раз (о ужас 05.gif ):
Цитата
не вижу принципиальной разницы между:
typedef unsigned char uint8;
и
#define uint8 unsigned char

В чем же все-таки проявляется эта разница в плане контроля типов? Разве в случае с #define, после работы препроцессора не происходит такая-же обработка компилятором? А то получается, что контроль типов производится только при наличии typedef. И объявление:
Код
typedef unsigned char uint8;
uint8 foo;

лучше, чем (после препроцессора):
Код
unsigned char foo;


Пока что я слышал от всех только общие рассуждения: "#define и typedef по разному обрабатываются ", "Дурной стиль без всякой на то надобности да и еще с побочными эффектами" и т.д. Но никто не дал ссылку или разъяснил почему это так в деталях.
Поделитесь, pls, своими знаниями, своим опытом. Приведите хоть один пример, где это дает ошибку. А то я уже запуган 05.gif , озираюсь в поисках опасностей, но нигде их не вижу.
Я ответ не знаю, и пока не могу найти ответ на него в первоисточниках, вот и хочу порасспрашивать знающих людей. Думаю, это еще многих может просветить.


p.s. Кстати, у вас были намного лучшие условия в плане интернета: я периодический доступ (пару раз в неделю на пару часов) получил только году в 98, а постоянный доступ на работе (с жуткими ограничениями) только в конце 2000 sad.gif
Go to the top of the page
 
+Quote Post
zltigo
сообщение Feb 29 2008, 21:50
Сообщение #11


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(Baser @ Mar 1 2008, 00:16) *
что применение typedef при определении структур улучшает именно контроль типов, а не удобство использования структуры.

И то и другое.
lint не приходилось в помощь компилятору использовать? misra?
Цитата
Приведите хоть один пример, где это дает ошибку
....
озираюсь в поисках опасностей, но нигде их не вижу.

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

От Вас жду хоть один пример "вредности" typedef.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- Baser   Странное поведение EWAVR 4.21A   Feb 28 2008, 21:59
- - zltigo   Цитата(Baser @ Feb 29 2008, 00:59) Вдруг ...   Feb 28 2008, 22:55
- - rezident   Объявления лучше делать именно в том модуле, где п...   Feb 28 2008, 23:12
||- - Baser   Ну, хорошо, будем считать, что я удовлетворился, в...   Feb 29 2008, 22:35
||- - zltigo   Цитата(Baser @ Mar 1 2008, 01:35) ... пох...   Feb 29 2008, 23:12
||- - Baser   Цитата(zltigo @ Mar 1 2008, 01:12) А как ...   Mar 1 2008, 14:21
||- - zltigo   Цитата(Baser @ Mar 1 2008, 17:21) ... и о...   Mar 1 2008, 17:34
||- - Baser   Вы неправильно поняли мои возражения против typede...   Mar 1 2008, 21:33
||- - zltigo   Цитата(Baser @ Mar 2 2008, 00:33) Если вы...   Mar 1 2008, 22:43
||- - Baser   Да, наверное, вы как всегда правы Цитата(zltig...   Mar 2 2008, 12:47
||- - zltigo   Цитата(Baser @ Mar 2 2008, 15:47) Да, нав...   Mar 2 2008, 13:02
||- - Baser   Цитата(zltigo @ Mar 2 2008, 15:02) Можно,...   Mar 2 2008, 22:34
|- - rezident   Цитата(Baser @ Feb 29 2008, 21:06) И все....   Feb 29 2008, 21:12
- - MALLOY2   По ходу вопрос, может я и гоню.... Не получается...   Mar 4 2008, 14:48
|- - Сергей Борщ   Так сделать невозможно - какой размер будет иметь ...   Mar 4 2008, 15:09
|- - Baser   Цитата(MALLOY2 @ Mar 4 2008, 16:48) Не по...   Mar 4 2008, 15:11
|- - zltigo   Цитата(Baser @ Mar 4 2008, 18:11) ...беск...   Mar 4 2008, 16:28
- - MALLOY2   Сорри это я опечатался естественно там указатель. ...   Mar 4 2008, 15:13
|- - zltigo   Цитата(MALLOY2 @ Mar 4 2008, 18:13) Кодty...   Mar 4 2008, 16:19
|- - Сергей Борщ   Цитата(MALLOY2 @ Mar 4 2008, 17:13) Кодty...   Mar 4 2008, 17:01
- - MALLOY2   Спс, помогло   Mar 4 2008, 16:27
- - chernenko   Чтобы не плодить темы решил написать здесь. Подска...   Oct 1 2008, 12:45
|- - Сергей Борщ   Цитата(chernenko @ Oct 1 2008, 15:45) Что...   Oct 1 2008, 13:09
|- - chernenko   Цитата(Сергей Борщ @ Oct 1 2008, 17:09) З...   Oct 10 2008, 07:02
- - IgorKossak   Ну у Вас опять же выделено место только под указат...   Oct 10 2008, 09:04
- - chernenko   IgorKossak, Да, точно. Глюканул. Всё работает. К...   Oct 10 2008, 10:07


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

 


RSS Текстовая версия Сейчас: 23rd July 2025 - 03:17
Рейтинг@Mail.ru


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