-
- Спасибо всем откликнувшимся. Вроде разобрался. Буду дальше копать. - mazur(11.08.2013 22:07)
- На пальцах Vit(2309 знак., 11.08.2013 09:38)
- а мне стало интересно, что static делает для функции, кроме прятания ее имени от линкера (ну то есть изъятием из public-а)? мурашки бывают вроде со static inline, но это уже с++ по-моему... - ыыыы(13.08.2013 17:30)
- Вроде какие-то из компиляторов/линкеров линкуют static-функции даже, если они нигде ни разу не вызываются/не используются. - rezident(14.08.2013 00:39 - 00:55)
- в последнее время многие Си-компилеры потребляют только static inline - просто inline не хотят, кроме того любят всякие прагмы типа inline force. Их и понять иногда можно - ведь если вдруг в inline функции есть вызов какой другой функции, компилер Vit(105 знак., 13.08.2013 19:55)
- Если inline не static, то может вызываться из другого модуля и у ней должен быть адрес. И будет call по адресу вместо вinlineивания. Кроме того, если текста функции нет в *.h, то вообще непонятно что там вinlineивать и опять же будет call. - fk0(14.08.2013 13:32)
- Это как? - Bill(13.08.2013 21:42)
- если inline foo1() вызывает некую foo2(), то компилятору неведомо, не вызовет ли в конечном счете foo2(), допустим, через вызов foo3(), функцию foo1(). тем самым заинлайнить вроде как и не получается - Vit(14.08.2013 00:05)
- Я немного не о том. Что значит "просто inline компиляторы не хотят". Они что, ошибку какую выдают, или что? - Bill(14.08.2013 14:07)
- да, ошибки выдают - Vit(14.08.2013 14:09)
- А ошибки какие? И компиляторы? - Bill(14.08.2013 14:47)
- Например, в самом свежем ЯРе для MSP430 линкер в несознанку уходит с Error[e46]: Undefined external "Foo" referred in ... - Vit(14.08.2013 15:10, ссылка)
- Ну тогда другой вопрос: как эти самые inline функции вы объявляете? - Bill(14.08.2013 15:32)
- пишу в хедере. если вкатать в Си-шник с inline, но без static, а прототип в хедер без inline, то собирается, но нахрена оно такое нужно, а если прототип с inline, то всё та же e46 - Vit(14.08.2013 15:34 - 15:38)
- Все понятно. Только нужно просто в заголовочном файле определить функцию как inline, а в Си файле вообще ничего не нужно определять. Ведь самой функции, как таковой, нет. Компилятор вместо вызова функции генерирует последовательность операторов, Bill(74 знак., 14.08.2013 15:51, ссылка)
- Повторяю - если в хедере объявить inline без static (как в Вашем примере), то e46. Может, ошибки и не будет, если хедер включать только в один модуль, но мне такое чудо не надо - Vit(14.08.2013 15:58, ссылка)
- а в хедере static inline? ничему ж не противоречит? - abivan(14.08.2013 16:07)
- да мне пофигу их мурашки. если нужна inline функция в куче модулей и с записью static inline в хедере этим компилятором/линкером оно собирается, то и ладно. а где-то и без static собиралось. а где-то __inline, а где-то INLINE. если бы не некоторые Vit(53 знак., 14.08.2013 16:13)
- без макроса не обойтись :-) abivan(131 знак., 14.08.2013 16:42)
- :) - Vit(14.08.2013 16:44)
- без макроса не обойтись :-) abivan(131 знак., 14.08.2013 16:42)
- да мне пофигу их мурашки. если нужна inline функция в куче модулей и с записью static inline в хедере этим компилятором/линкером оно собирается, то и ладно. а где-то и без static собиралось. а где-то __inline, а где-то INLINE. если бы не некоторые Vit(53 знак., 14.08.2013 16:13)
- У меня все прекрасно собирается без всяких ошибок. А заголовочный файл является общим для всего проекта. Поэтому он включается во все модули проекта. - Bill(14.08.2013 16:05)
- ЗЫ. Проверьте, плз, есть ли у Вас вызовы одной inline-функции в разных модулях, а то на пустышки линкер не ругается - Vit(14.08.2013 16:19)
- Конечно есть. Только линкер здесь ни причем. До него дело лаже не доходит. Это же inline функции! Bill(212 знак., 14.08.2013 19:19)
- у ЯРя линкеру не нравится C99 - какие у них отношения?:) - Vit(14.08.2013 20:55)
- Я же пример сгенерированного кода привел. Или из него ничего не ясно? - Bill(14.08.2013 22:11)
- Ясно только, что по
одному вызову двух функцийодной подстановке сгенерировалось. Двухвызовов одной функцииодинаковых подстановок не видел. И то, что ошибку описывает IAR, Вас не волнует - Vit(14.08.2013 22:39)- Вы хотите, чтобы я все листинги проекта выложил? - Bill(15.08.2013 06:30)
- Если у Вас IAR под 430, то интересно включено ли C99 и какой уровень оптимизации. Больше ничего не нужно. - Vit(15.08.2013 07:42)
- Увы, у меня AVR V5.51 - Bill(15.08.2013 08:57)
- Если у Вас IAR под 430, то интересно включено ли C99 и какой уровень оптимизации. Больше ничего не нужно. - Vit(15.08.2013 07:42)
- Вы хотите, чтобы я все листинги проекта выложил? - Bill(15.08.2013 06:30)
- Ясно только, что по
- Я же пример сгенерированного кода привел. Или из него ничего не ясно? - Bill(14.08.2013 22:11)
- у ЯРя линкеру не нравится C99 - какие у них отношения?:) - Vit(14.08.2013 20:55)
- Конечно есть. Только линкер здесь ни причем. До него дело лаже не доходит. Это же inline функции! Bill(212 знак., 14.08.2013 19:19)
- Я за Вас рад:) Когда смените компилятор и увидите какую-нить хрень типа е46, вспомните меня:) - Vit(14.08.2013 16:08)
- Я тогда вам обязательно сообщу. ;) - Bill(14.08.2013 16:09)
- ЗЫ. Проверьте, плз, есть ли у Вас вызовы одной inline-функции в разных модулях, а то на пустышки линкер не ругается - Vit(14.08.2013 16:19)
- а в хедере static inline? ничему ж не противоречит? - abivan(14.08.2013 16:07)
- Повторяю - если в хедере объявить inline без static (как в Вашем примере), то e46. Может, ошибки и не будет, если хедер включать только в один модуль, но мне такое чудо не надо - Vit(14.08.2013 15:58, ссылка)
- Все понятно. Только нужно просто в заголовочном файле определить функцию как inline, а в Си файле вообще ничего не нужно определять. Ведь самой функции, как таковой, нет. Компилятор вместо вызова функции генерирует последовательность операторов, Bill(74 знак., 14.08.2013 15:51, ссылка)
- пишу в хедере. если вкатать в Си-шник с inline, но без static, а прототип в хедер без inline, то собирается, но нахрена оно такое нужно, а если прототип с inline, то всё та же e46 - Vit(14.08.2013 15:34 - 15:38)
- Ну тогда другой вопрос: как эти самые inline функции вы объявляете? - Bill(14.08.2013 15:32)
- Например, в самом свежем ЯРе для MSP430 линкер в несознанку уходит с Error[e46]: Undefined external "Foo" referred in ... - Vit(14.08.2013 15:10, ссылка)
- А ошибки какие? И компиляторы? - Bill(14.08.2013 14:47)
- да, ошибки выдают - Vit(14.08.2013 14:09)
- Хвостовая рекурсия прекрасно оптимизируется в страшный goto. - fk0(14.08.2013 13:30)
- Я немного не о том. Что значит "просто inline компиляторы не хотят". Они что, ошибку какую выдают, или что? - Bill(14.08.2013 14:07)
- если inline foo1() вызывает некую foo2(), то компилятору неведомо, не вызовет ли в конечном счете foo2(), допустим, через вызов foo3(), функцию foo1(). тем самым заинлайнить вроде как и не получается - Vit(14.08.2013 00:05)
- а чем рекурсивный вызов плох? по-моему в цикл его мало какой(?) С-компилер разворачивает. да, стек может рекурсия убить, но это не компилера забота. по-хорошему (если программист думает мозгОм) inline она уже и есть статик, то есть она действует ыыыы(428 знак., 13.08.2013 20:48)
- рекурсивный вызов это уже не inline - запись а-ля макрос, а вызов с прологами/эпилогами - Vit(14.08.2013 00:08, ссылка)
- а мне стало интересно, что static делает для функции, кроме прятания ее имени от линкера (ну то есть изъятием из public-а)? мурашки бывают вроде со static inline, но это уже с++ по-моему... - ыыыы(13.08.2013 17:30)
- Есть в WinAVR настройка, чтобы после ресета обнулялась вся ОЗУ? Или для этого свою функцию нужно писать? - mazur(11.08.2013 03:34)
- Как сделано в WinAVR, не знаю, но в IAR существует startup-код, который вставляется неявно перед процедурой main(). Он инициализирует области RAM константами и устанавливает указатели стеков. Часто он пишется на ассемблере. Наверняка, что-то Ксения(267 знак., 13.08.2013 15:29)
- Есть такое же в WinAvr Apтём(379 знак., 13.08.2013 15:46)
- Все глобальные (global) и статические (static) переменные обычно попадают в секцию, которая автоматически очищается (инициализируется нулями) еще до выполнения main, если только они не объявляются одновременно с инициализацией их явными rezident(694 знак., 11.08.2013 04:11 - 04:14)
- Настройки такой наверное нет, но свою функцию сразу после старта запустить можно: Apтём(441 знак., 11.08.2013 04:05)
- Интересно только, что означает это выражение Bill(51 знак., 12.08.2013 10:09)
- это ж константа, время исполнения не жрет - можно писать что угодно. ну и если вдруг захочется на 1 поменять - то все уже готово :) - ыыыы(13.08.2013 17:36)
- Я всегда пишу единообразно. Тогда не нужно ничего менять. Bill(183 знак., 13.08.2013 19:18)
- ИМХО, низковато. Вот еще вверх на полуровня абстракции - и хорошо. То есть в тексте программе должно быть то, что в Ваших комментариях: LED_OFF; LED_ON; ... А эти |= и &= пусть лежат в платформозависимом хидере. Не надо эти субпродукты на экран Юра(63 знак., 14.08.2013 00:21, )
- И как именно вы предлагаете писать? - Bill(14.08.2013 07:10)
- Да пусть в том же хидере, где Вы указали, что #define LED_PORT PORTB и что #define RED_LED_PIN 6, - описать чуть ниже для удобной работы несколько строк вроде: #define RED_LED_ON LED_PORT |= (1 < < RED_LED_PIN). И все. Лучше сразу там описать Юра(897 знак., 14.08.2013 09:10, )
- А что мешает к порту "привязать" еще что-то, например, Bill(246 знак., 14.08.2013 11:17)
- Только разводка)) Ведь реле-1 может быть на одном порту, а реле-2 на другом. А реле-3и4 - сами понимаете, на третьем. И что? В программе писать PORT_RELE_3 |= (1 < < BIT_RELE_4) ? Имена портов, как и операции |= &= не должны (по-моему) светиться Юра(639 знак., 14.08.2013 11:38, )
- того же мнения - Vit(14.08.2013 11:57)
- Только разводка)) Ведь реле-1 может быть на одном порту, а реле-2 на другом. А реле-3и4 - сами понимаете, на третьем. И что? В программе писать PORT_RELE_3 |= (1 < < BIT_RELE_4) ? Имена портов, как и операции |= &= не должны (по-моему) светиться Юра(639 знак., 14.08.2013 11:38, )
- +1. Только косметики чуток добавляю - #define RED_LED_ON() do{ LED_PORT |= (1 < < RED_LED_PIN); }while(0) Vit(168 знак., 14.08.2013 09:21)
- do-while зачем? просто { } не достаточно? - abivan(14.08.2013 12:00)
- это чтобы нужно было точку-с-запятой поставить if(mode)RED_LED_ON(); else GREEN_LED_ON(); - Vit(14.08.2013 12:04)
- ясно. А ведь было уже. Забуду ведь опять, потому как не использую. Лишней писанины много, а когда раз в год ошибка появляется скобки видимо ставлю после if перед else. А кста, какой-то стандарт(MISRA?) тут требовал скобки ставить после if всегда abivan(34 знак., 14.08.2013 12:15)
- Это такая дырочка в синтаксисе Си. Способы борьбы разные. - Vit(14.08.2013 12:22)
- ясно. А ведь было уже. Забуду ведь опять, потому как не использую. Лишней писанины много, а когда раз в год ошибка появляется скобки видимо ставлю после if перед else. А кста, какой-то стандарт(MISRA?) тут требовал скобки ставить после if всегда abivan(34 знак., 14.08.2013 12:15)
- это чтобы нужно было точку-с-запятой поставить if(mode)RED_LED_ON(); else GREEN_LED_ON(); - Vit(14.08.2013 12:04)
- Нет, тогда я делаю функции inline. Не люблю пользоваться препроцессором. - Bill(14.08.2013 11:20)
- почему такая нелюбовь? препроцессор как управдом - друг программиста - Snaky(14.08.2013 11:27)
- Препроцессор в Си как-никак всего лишь надстройка. И его поведение бывает непредсказуемо. Bill(201 знак., 14.08.2013 11:49)
- не связывал факт надстройки с предсказуемостью. Snaky(329 знак., 14.08.2013 12:04)
- Ну, скажем, такой простой пример: Bill(157 знак., 14.08.2013 12:21)
- ; после PORTC лишняя - Leks(14.08.2013 12:43)
- Молодец! А теперь представьте, что определение находится Bill(92 знак., 14.08.2013 12:47)
- как это нет? Просто нужны соответствующие средства. Окно превью показывает объявление для символа под курсором SlickEdit, если что. abivan(14.08.2013 13:14)
- Это не непредсказуемость, а сложности отладки. И они - да, есть. Но после пары раз быстро запоминается как же не нужно делать:) - Vit(14.08.2013 12:52)
- Да ведь и пример-то ну очень простой. - Bill(14.08.2013 12:53)
- Молодец! А теперь представьте, что определение находится Bill(92 знак., 14.08.2013 12:47)
- Вы много хотите от компилятора. - Vladimir Ljaschko(14.08.2013 12:37)
- Как раз немного. Компилятор стандартный. - Bill(14.08.2013 12:39)
- В проекте нет main? Не подключили io*.h? )) - Юра(14.08.2013 12:31, )
- Это тут ни причем. Все на месте. И, тем не менее, ошибка! Попробуйте найти. - Bill(14.08.2013 12:35)
- Вы серьёзно? Или нет? ;) - Vit(14.08.2013 12:37)
- Абсолютно серьезно. Попробуйте и вы найти ошибку. - Bill(14.08.2013 12:38)
- точка-с-запятой (плохо болдится;) - Vit(14.08.2013 12:40)
- А ошибка-то в чем? - Bill(14.08.2013 12:42)
- в точке с запятой после PORTC - обычная криворукость - точки с запятой в макросах не стОит ставить вне блоков, иначе пионэрские ашипки полезут. Никакой непредсказуемости. - Vit(14.08.2013 12:45)
- Само собой - криворукость. Только ошибку-то вы не сразу нашли. А такую ошибку Bill(83 знак., 14.08.2013 12:51)
- Я-то сразу нашёл - просто не поверил, что Вы такое спрашиваете. Тем более тут Юра как раз и писал, что подобный хлам надо окучивать и выносить в отдельное место. По ссылке специально выделил точку-с-запятой жирным (заболдил), но почти Vit(11 знак., 14.08.2013 12:57 - 13:00, ссылка)
- Но, опять же, Юра как-то сразу сдался. А я еще раз повторяю: препроцессор - это прокладка между исходным текстом и компилятором. Он является источником дополнительных ошибок, которые часто бывает трудно обнаружить. Особенно в тех случаях когда Bill(84 знак., 14.08.2013 13:06)
- Обычно в среде можно сохранить текст после препроцессора, тогда легко увидеть ошибки, а если смотреть лень, то скормить это компилятору. - Vladimir Ljaschko(14.08.2013 13:11)
- Конечно можно. Все определяется только затраченными усилиями и временем. - Bill(14.08.2013 13:15)
- Юра просто получил эмоциональный взрыв:))) О сложностях при использовании препроцессора говорить можно долго. Но это не повод его не использовать:) - Vit(14.08.2013 13:11)
- Я не говорю, что его не нужно использовать. Просто нужна мера, во всем. - Bill(14.08.2013 13:13)
- Вот сборничек опасностей:) --> - Vit(14.08.2013 13:26, ссылка, ссылка)
- Особенно обратил внимание на Bill(206 знак., 14.08.2013 13:43)
- Тогда это для Вас будет полезно :) Vladimir Ljaschko(3798 знак., 14.08.2013 13:46)
- Особенно обратил внимание на Bill(206 знак., 14.08.2013 13:43)
- Мера зависит от опыта, и это касается не только препроцессора ;) - Vladimir Ljaschko(14.08.2013 13:23)
- На это трудно что-либо возразить. - Bill(14.08.2013 13:47)
- Для обращения к портам вполне годится. - Vit(14.08.2013 13:22)
- Определения. констант, портов и т.п. Правда, опять же, по возможности, в последнее время для определения констант Bill(45 знак., 14.08.2013 13:34)
- Вот сборничек опасностей:) --> - Vit(14.08.2013 13:26, ссылка, ссылка)
- Я не говорю, что его не нужно использовать. Просто нужна мера, во всем. - Bill(14.08.2013 13:13)
- Юра вообще слабак. Сразу #define Сдаюсь; - Юра(14.08.2013 13:08, )
- Обычно в среде можно сохранить текст после препроцессора, тогда легко увидеть ошибки, а если смотреть лень, то скормить это компилятору. - Vladimir Ljaschko(14.08.2013 13:11)
- Я не сразу, около 80 мс потребовалось. Наверно, питание плохое. - Юра(14.08.2013 13:02, )
- Согласен, соврал:) - пока чашечку с кофе поставил... - Vit(14.08.2013 13:04)
- Может надо было посложнее пример придумать? - Bill(14.08.2013 13:08)
- Надо было. А то этот в аккурат показал, что Юра прав:) - Vit(14.08.2013 13:12)
- Может надо было посложнее пример придумать? - Bill(14.08.2013 13:08)
- Согласен, соврал:) - пока чашечку с кофе поставил... - Vit(14.08.2013 13:04)
- Но, опять же, Юра как-то сразу сдался. А я еще раз повторяю: препроцессор - это прокладка между исходным текстом и компилятором. Он является источником дополнительных ошибок, которые часто бывает трудно обнаружить. Особенно в тех случаях когда Bill(84 знак., 14.08.2013 13:06)
- Я-то сразу нашёл - просто не поверил, что Вы такое спрашиваете. Тем более тут Юра как раз и писал, что подобный хлам надо окучивать и выносить в отдельное место. По ссылке специально выделил точку-с-запятой жирным (заболдил), но почти Vit(11 знак., 14.08.2013 12:57 - 13:00, ссылка)
- Само собой - криворукость. Только ошибку-то вы не сразу нашли. А такую ошибку Bill(83 знак., 14.08.2013 12:51)
- в точке с запятой после PORTC - обычная криворукость - точки с запятой в макросах не стОит ставить вне блоков, иначе пионэрские ашипки полезут. Никакой непредсказуемости. - Vit(14.08.2013 12:45)
- А ошибка-то в чем? - Bill(14.08.2013 12:42)
- точка-с-запятой (плохо болдится;) - Vit(14.08.2013 12:40)
- Абсолютно серьезно. Попробуйте и вы найти ошибку. - Bill(14.08.2013 12:38)
- Сдаюсь; - Юра(14.08.2013 12:36, )
- и я. кста Var;=0 выдает такуюже ошибку. line 1; column 5; expression syntax - abivan(14.08.2013 12:47)
- ;))) - Bill(14.08.2013 12:52)
- и я. кста Var;=0 выдает такуюже ошибку. line 1; column 5; expression syntax - abivan(14.08.2013 12:47)
- Вы серьёзно? Или нет? ;) - Vit(14.08.2013 12:37)
- Это тут ни причем. Все на месте. И, тем не менее, ошибка! Попробуйте найти. - Bill(14.08.2013 12:35)
- ; после PORTC лишняя - Leks(14.08.2013 12:43)
- Ну, скажем, такой простой пример: Bill(157 знак., 14.08.2013 12:21)
- не связывал факт надстройки с предсказуемостью. Snaky(329 знак., 14.08.2013 12:04)
- Препроцессор в Си как-никак всего лишь надстройка. И его поведение бывает непредсказуемо. Bill(201 знак., 14.08.2013 11:49)
- А я наоборот, считаю inline-функции костылями и использую их только если без них не складывается - Vit(14.08.2013 11:26, ссылка)
- так и я так же поступаю. Просто я лучше оформлю манипуляцию с портом в виде inline функции, а не виде макроопределения с параметрами. Впрочем, все люди пишут исходя из своих собственных представлений и своего собственного опыта. А и представления, Bill(31 знак., 14.08.2013 11:57)
- Да, это просто две стороны одной медали. По большому счету неважно, под именем макроса или под именем инлайн-функции Вы скрываете внутренности операций. Удобная и наглядная упаковка (говорящая, но без лишних подробностей) + локальное место для Юра(20 знак., 14.08.2013 12:13, )
- Я Вас не заставляю и не уговариваю. Просто когда пишешь для нескольких архитектур и под разные компиляторы, задалбывает запоминать различия синтаксиса. Но это полбеды, а вот когда Кейлу в зависимости от версии нужно ещё и прагму разную ставить - Vit(175 знак., 14.08.2013 12:12)
- не использовал инлайн потому как не было их у меня(не поддерживалось) да и сейчас не поддерживается в "моем" компиляторе. Вопрос для общего развития, так сказать, как использовать инлайн в разных модулях? В хедер поместить? - abivan(14.08.2013 12:05)
- Да. Компилятор просто должен "знать" как скомпилировать соответствующую функцию. Маленький пример: Bill(567 знак., 14.08.2013 12:15 - 12:26)
- так и я так же поступаю. Просто я лучше оформлю манипуляцию с портом в виде inline функции, а не виде макроопределения с параметрами. Впрочем, все люди пишут исходя из своих собственных представлений и своего собственного опыта. А и представления, Bill(31 знак., 14.08.2013 11:57)
- почему такая нелюбовь? препроцессор как управдом - друг программиста - Snaky(14.08.2013 11:27)
- do-while зачем? просто { } не достаточно? - abivan(14.08.2013 12:00)
- А что мешает к порту "привязать" еще что-то, например, Bill(246 знак., 14.08.2013 11:17)
- Да пусть в том же хидере, где Вы указали, что #define LED_PORT PORTB и что #define RED_LED_PIN 6, - описать чуть ниже для удобной работы несколько строк вроде: #define RED_LED_ON LED_PORT |= (1 < < RED_LED_PIN). И все. Лучше сразу там описать Юра(897 знак., 14.08.2013 09:10, )
- И как именно вы предлагаете писать? - Bill(14.08.2013 07:10)
- ИМХО, низковато. Вот еще вверх на полуровня абстракции - и хорошо. То есть в тексте программе должно быть то, что в Ваших комментариях: LED_OFF; LED_ON; ... А эти |= и &= пусть лежат в платформозависимом хидере. Не надо эти субпродукты на экран Юра(63 знак., 14.08.2013 00:21, )
- Я всегда пишу единообразно. Тогда не нужно ничего менять. Bill(183 знак., 13.08.2013 19:18)
- Для наглядности. И чтобы представлять что туда писать нужно. Apтём(123 знак., 13.08.2013 03:10 - 03:29)
- И как вы пишите, если нужно сбросить Bill(63 знак., 13.08.2013 07:09)
- Как и все пишу - Apтём(114 знак., 13.08.2013 14:44)
- И как вы пишите, если нужно сбросить Bill(63 знак., 13.08.2013 07:09)
- Очень удобно, чтобы видеть, что в настоящий момент этот бит выключен. Не нужно комменты писать. - Vladimir Ljaschko(12.08.2013 10:20)
- это ж константа, время исполнения не жрет - можно писать что угодно. ну и если вдруг захочется на 1 поменять - то все уже готово :) - ыыыы(13.08.2013 17:36)
- Интересно только, что означает это выражение Bill(51 знак., 12.08.2013 10:09)
- Как сделано в WinAVR, не знаю, но в IAR существует startup-код, который вставляется неявно перед процедурой main(). Он инициализирует области RAM константами и устанавливает указатели стеков. Часто он пишется на ассемблере. Наверняка, что-то Ксения(267 знак., 13.08.2013 15:29)
- Edit. Хедеры добавляются в другие файлы, если используются константы или переменные этого хедера? Не совсем понял правила добавления хедеров. mazur(138 знак., 10.08.2013 22:43 - 23:02)
- Да, так: Apтём(555 знак., 10.08.2013 23:11)
- Объявите сам enum в хидере, а переменную его типа в С-модуле. Если речь идет о "enum { ST_KBD=0 }", то он у вас обявлен в вероном месте, только дайте ему имя, что можно было им пользваться. - Ксения(10.08.2013 23:06 - 23:10)
- Можно на примере? - mazur(10.08.2013 23:08)
- Пример: Ксения(495 знак., 10.08.2013 23:15 - 23:24)
- Хидер: mazur(475 знак., 10.08.2013 23:37)
- Можно магическое слово typedef использовать: Bill(228 знак., 11.08.2013 18:10)
- Спасибо, ваш вариант сработал. - mazur(11.08.2013 22:04)
- Для примера привожу содержимое своего заголовочного файла: Bill(4625 знак., 12.08.2013 09:22)
- Спасибо, ваш вариант сработал. - mazur(11.08.2013 22:04)
- Вы выражение "kbd_states _keys = KEYS_NONE;" без хидера компилировать пытались? Напрасно! Откуда компилятору без хидера знать, что такое kbd_states? Ксения(478 знак., 11.08.2013 17:03 - 17:11)
- 1 - Поубирал по вашему совету лишние подключения хидеров. Объявил переменные как мне тут и посоветовали. mazur(1244 знак., 11.08.2013 20:07)
- Мне уже надоело объясняить вам очевидные вещи. В ВАШЕМ хидере enum объявлен БЕЗ имени! А стало быть "kbd_states" нигде не определяется. Именно это и ставит в тупик компилятор, когда пишите "kbd_states _keys = KEYS_NONE". Если вы готовы следовать Ксения(63 знак., 11.08.2013 20:54)
- Я еще по jopa понял. :) В любом случае, спасибо. - mazur(11.08.2013 22:06)
- И в чём теперь непонятка? Apтём(186 знак., 11.08.2013 20:23)
- Мне уже надоело объясняить вам очевидные вещи. В ВАШЕМ хидере enum объявлен БЕЗ имени! А стало быть "kbd_states" нигде не определяется. Именно это и ставит в тупик компилятор, когда пишите "kbd_states _keys = KEYS_NONE". Если вы готовы следовать Ксения(63 знак., 11.08.2013 20:54)
- 1 - Поубирал по вашему совету лишние подключения хидеров. Объявил переменные как мне тут и посоветовали. mazur(1244 знак., 11.08.2013 20:07)
- Просто _keys = KEYS_NONE; - 123(11.08.2013 16:28, )
- Можно магическое слово typedef использовать: Bill(228 знак., 11.08.2013 18:10)
- Хидер: mazur(475 знак., 10.08.2013 23:37)
- Пример: Ксения(495 знак., 10.08.2013 23:15 - 23:24)
- Можно на примере? - mazur(10.08.2013 23:08)
- Прочие пожелания: Ксения(627 знак., 10.08.2013 22:48 - 22:51)
- -> - zeleny(10.08.2013 22:45, ссылка)
- Рыба для глобальных флагов Daniilvb(679 знак., 10.08.2013 22:18)
- Угу. Вроде получилось. extern если разные модули используют. static если в пределах одного модуля. Так? - mazur(10.08.2013 22:09)
- Если в пределах одного модуля, то определяется переменная вне функций(static необязательно), но в этом модуле. Daniilvb(337 знак., 10.08.2013 22:32)
- static имеет и другие значения - koyodza(10.08.2013 22:23)
- Не понял, зачем в одном файле несколько объявлений одной переменной. - Vladimir Ljaschko(10.08.2013 21:51)
- Вот и спрашиваю, как правильно сделать. Я не могу понять к какому виду относится эта переменная st_flags и как ее правильно объявлять. То вообще функция не компилируется, то пустая. В том виде как выложил пример скомпилировалось. - mazur(10.08.2013 21:55)
- Судя по всему, st_flags это не глобальная переменна, а имя элемента массива сруктур "struct {u08 st_flags; u16 st_cnt} Sys_Timers_Queue[ST_QUANTITY];". Если это так, то объявлять st_flags глобальной переменной вы не должны. Но, судя по Ксения(61 знак., 10.08.2013 22:34 - 22:36)
- Нет. На ассемблере для уменьшения кода и времени я сделал в старшем регистре переменную FLAGS. Один из флагов - признак очередного отщелкивания таймера настроенного на тик 1, 10 или 100 мс. mazur(126 знак., 10.08.2013 22:39)
- А вы не слушайте всяких :). Си похож на ассемблер гораздо сильнее, чем это кажется на первый взгляд. Ассемблером вы владеете превосходно, вот и прислушивайтесь к своему ассеблерному опыту. Си - послушный язык, и вы должны диктовать ему свою волю, Ксения(402 знак., 10.08.2013 23:01)
- Ассемблером он не владеет, а обладает. Женщине разница должна быть очень хорошо понятна :)) - MBedder(11.08.2013 20:14)
- Спасибо! :) - mazur(10.08.2013 23:04)
- Хм.. Apтём(121 знак., 10.08.2013 22:59)
- А вы не слушайте всяких :). Си похож на ассемблер гораздо сильнее, чем это кажется на первый взгляд. Ассемблером вы владеете превосходно, вот и прислушивайтесь к своему ассеблерному опыту. Си - послушный язык, и вы должны диктовать ему свою волю, Ксения(402 знак., 10.08.2013 23:01)
- Нет. На ассемблере для уменьшения кода и времени я сделал в старшем регистре переменную FLAGS. Один из флагов - признак очередного отщелкивания таймера настроенного на тик 1, 10 или 100 мс. mazur(126 знак., 10.08.2013 22:39)
- Судя по всему, st_flags это не глобальная переменна, а имя элемента массива сруктур "struct {u08 st_flags; u16 st_cnt} Sys_Timers_Queue[ST_QUANTITY];". Если это так, то объявлять st_flags глобальной переменной вы не должны. Но, судя по Ксения(61 знак., 10.08.2013 22:34 - 22:36)
- Вот и спрашиваю, как правильно сделать. Я не могу понять к какому виду относится эта переменная st_flags и как ее правильно объявлять. То вообще функция не компилируется, то пустая. В том виде как выложил пример скомпилировалось. - mazur(10.08.2013 21:55)
- И ещё: Apтём(307 знак., 10.08.2013 21:51)
- Итак. 1 раз в хидере extern volatile u08 st_flags; или extern u08 st_flags; если эта переменная не используется в прерываниях. mazur(101 знак., 10.08.2013 22:05)
- Если используется в прерываниях то добавлять volatile. - Apтём(10.08.2013 22:56)
- Верно, только хидеры принято включать в начало C-шного файла, а не втыкать где попало. А используется ли эта переменная в прерываниях или нет, значения не имеет. - Ксения(10.08.2013 22:07)
- Итак. 1 раз в хидере extern volatile u08 st_flags; или extern u08 st_flags; если эта переменная не используется в прерываниях. mazur(101 знак., 10.08.2013 22:05)
- есть правило: всегда старайся сделать минимально возможную область видимости. Если можешь вместо глобальной переменной использовать переменную, видимую только в пределах модуля - хорошо. Если можешь вместо переменной, видимой в пределах модуля, koyodza(33 знак., 10.08.2013 21:46)
- Объявляете "extern u08 st_flags;" в хидере, и включаете его во все модули проекта, которые st_flags используют. Однако заводите его "u08 st_flags;" только одном из модулей! И не в коем случае не в каждом. А вы, кажется, кучу клонов ему завели. Ксения(35 знак., 10.08.2013 21:38 - 21:40)
- Под модулями понимаем файл или подпрограммы-функцмм? Убрал перед функциями в *.c u08 st_flags - не компилируется. E:\ATMEL\C\KBD_DRV\default/../sys_timer.c:14: undefined reference to `st_flags' - mazur(10.08.2013 21:51)
- Под модулями понимаем C-файлы, включенные в проект. Если sys_timer.c не компилируется, значит вы забыли вставить в него хидер, где объявлен ваш st_flags. - Ксения(10.08.2013 22:00 - 22:06)
- Напишите в начале ц-файла Apтём(108 знак., 10.08.2013 21:56)
- Под модулями понимаем файл или подпрограммы-функцмм? Убрал перед функциями в *.c u08 st_flags - не компилируется. E:\ATMEL\C\KBD_DRV\default/../sys_timer.c:14: undefined reference to `st_flags' - mazur(10.08.2013 21:51)