Обсуждаем контроллеры компании Atmel.
Ответить

Re: Нескольно простых вопросов о программировании AVR на Си.

Чт мар 26, 2020 13:15:59

Создать заголовочный файл для переменных.

Код:
#ifdef MAIN_C
#define MAIN_EXTERNAL
#else
#define MAIN_EXTERNAL extern
#endif // MAIN_C

//переменные
MAIN_EXTERNAL type var;


Включить данный заголовочник для каждого файла проекта .с. В одном файле, лучше main.c, добавить
Код:
#define MAIN_C

Re: Нескольно простых вопросов о программировании AVR на Си.

Чт мар 26, 2020 17:26:02

спасибо :)

Re: Нескольно простых вопросов о программировании AVR на Си.

Чт мар 26, 2020 21:36:55

KorbenDallas, не говорите ерунды. Обычный C, с ассемблерными вставками. Ну и ещё идиотскими отступами по коду.


Нет. Никакой ерунды. В языке С на уровне файла не допускаются инициализации вида

Код:
const int A = 42;
const int B = A;  /* <- Ошибка: инициализатор должен быть константным выражением! */


Переменные, объявленные с `const`, в языке С (в отличие от С++) не являются константами времени компиляции и не могут быть использованы там, где требуются константные выражения. В частности, `const` переменные не могут быть использованы для инициализации переменных со статическим классом хранения, то есть не могут быть использованы для инициализации других переменных уровня файла.

Вышеприведенный код (как и код автора вопроса) принимается компиляторами группы GCC/Clang только в качестве нестандартного расширения языка С. Это расширение появилось в GCC начиная с версии 8

GCC 7.3: https://godbolt.org/z/0wEtZJ
GCC 8.1: https://godbolt.org/z/Tw8kL9

Но не под GCC, а под какой-то другой компилятор


Нет. Именно под GCC или совместимый компилятор (Clang?). Остальные компиляторы С по прежнему продолжают честно отлавливать эту ошибку.

---

подскажите, как сделать так, чтобы переменная, объявленная в одном файле, была видна во всех остальных?


1. В стандартном языке С вам придется идти по классическому пути: создать заголовочный файл с extern-объявлением переменной (без инициализатора).

Код:
extern int a;


А в одном из файлов реализации сделать определение этой переменной (возможно с инициализатором)

Код:
int a = 42;


2. Многие компиляторы языка С (GCC, Clang, MSVC и т.д. и т.п.) поддерживают популярное нестандартное расширение языка С, разрешающее множественные глобальные определения переменных между разными единицами трансляции, при условии, что такие переменные не содержат инициализатора. Это позволяет вам напрямую, прямо в заголовочном файле сделать определение переменной

Код:
int a;


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

3. В языке С++ у вас есть либо классический способ (см. 1), либо определение переменной прямо в заголовочном файле как `inline`

Код:
inline int a = 42;


Последний вариант доступен начиная с С++17
Последний раз редактировалось KorbenDallas Чт мар 26, 2020 22:09:32, всего редактировалось 4 раз(а).

Re: Нескольно простых вопросов о программировании AVR на Си.

Чт мар 26, 2020 21:38:05

KorbenDallas, уже месяц назад написали, что это CodeVision AVR. Там видимо тоже подобные "нестандартные" расширения допускаются. По структуре объявления прерываний и остальному видно прекрасно, что это CVAVR. И прошивку уже в CVAVR собрали на тот вопрос и работает она. Че вы некропостом этим пытаетесь доказать?

Re: Нескольно простых вопросов о программировании AVR на Си.

Чт мар 26, 2020 21:55:47

KorbenDallas, уже месяц назад написали, что это CodeVision AVR. Там видимо тоже подобные "нестандартные" расширения допускаются.


Видимо да.

Че вы некропостом этим пытаетесь доказать?


Во-первых, тут нет никакого "доказательства". Доказывать можно теорему. Я лишь упомянул аксиомы языка. Данная тема, напомню, посвящена именно языку С.
Во-вторых, "пытаться" я не смогу даже если захочу: я сказал свое слово - все вопросы сразу разрешились.
В-третьих, оставьте, пожалуйста, такое понятие как "некропост" там, где ему самое место - в конце девяностых-начале двухтысячных. Такого понятия уже давно не существует. Это, если хотите, уже давно некропонятие ))

Re: Нескольно простых вопросов о программировании AVR на Си.

Чт мар 26, 2020 22:23:19

KorbenDallas писал(а):Переменные, объявленные с `const`, в языке С (в отличие от С++) не являются константами времени компиляции
Хм, это было интересно.
Код:
static const uint32_t R_POT_H   = 4700;         // Pot pull-up resistor
static const uint32_t R_POT     = 100000;       // Pot resistance

// TODO: calibration settings for potentiomenters
static const int32_t R_POT_TH   = 67;           // Experimental threshold
static const int32_t R_POT_MAX  = (((ADC_MAX) * R_POT / (R_POT + R_POT_H)) - R_POT_TH);
Использовал этот код для STM32 и даже не подозревал, что версией компилятора пониже я бы это мог и не собрать.

Тем больше хочется уйти в сторону C++, где на constexpr можно вообще чудеса творить...

Re: Нескольно простых вопросов о программировании AVR на Си.

Чт мар 26, 2020 22:29:58

Именно поэтому в С для объявления именно констант (а не "неизменяемых переменных") по-прежнему доминирует `#define`. В ряде случаев можно воспользоваться `enum`. А вот применимость `const` объявлений очень ограничена.

Даже если компилятор позволяет использовать `const` переменные для статической инициализации, он скорее всего не позволит использовать их для указания ширины bit-field, для формирования case-метки, для указания размера не-VLA массива и т.п.

Re: Нескольно простых вопросов о программировании AVR на Си.

Чт мар 26, 2020 22:38:13

Ну конкретно на AVR применимость есть вот такая: https://gcc.gnu.org/onlinedocs/gcc/Name ... paces.html
Конечно это опять же не стандарт языка... но архитектура такова.

Re: Нескольно простых вопросов о программировании AVR на Си.

Пт мар 27, 2020 06:20:14

На самом деле, особенно применительно к микроконтроллерами, особой разницы между #define, enum и static const я уже давно не вижу. Оптимизация (-Os) для всех случаев приводит к побайтно идентичному коду, из моего опыта.

А контакты и встраиваемые функции использовать удобнее (по сравнению с теми же макросами, ввиду нулевой разницы на выходе). С ними IDE обычно без проблем работают, давая более адекватные подсказки при автодополнении кода.

Re: Нескольно простых вопросов о программировании AVR на Си.

Пт мар 27, 2020 07:47:03

WiseLord писал(а):особой разницы между #define, enum и static const я уже давно не вижу
разница появляется в тех случаях, когда создаются указатели на эти объявления - хоть Си является языком нестрогой типизации, в большинстве компиляторов предусмотрены варнинги для формально несовпадающих типов, что иной раз сильно выручает.

Re: Нескольно простых вопросов о программировании AVR на Си.

Пт мар 27, 2020 20:55:16

На самом деле, особенно применительно к микроконтроллерами, особой разницы между #define, enum и static const я уже давно не вижу. Оптимизация (-Os) для всех случаев приводит к побайтно идентичному коду, из моего опыта.


Это нормально. Сгенерированный код запросто может оказаться идентичным даже если убрать `const` вообще. Если компилятор знает значение переменной в конкретном контексте, то всякий уважающий себя оптимизирующий компилятор не преминет подставить в сгенерированный код ее значение, вместо того, чтобы формировать полноценное обращение к хранилищу. `const` лишь дает ему больше прав.

В данном же случае речь именно о формальной корректности с точки зрения языка.

Добавлено after 8 minutes 21 second:
разница появляется в тех случаях, когда создаются указатели на эти объявления - хоть Си является языком нестрогой типизации, в большинстве компиляторов


Язык С является языком со очень строгой типизацией.

В строгости типизации языки С и С++ фактически идентичны. Различия в типизации между С и С++ сводятся только к возможности неявного преобразования указателей из `void *` в С и возможности неявного преобразования из `int` в `enum` в С (плюс еще ворох нюансов помельче).

предусмотрены варнинги для формально несовпадающих типов, что иной раз сильно выручает.


Все эти "варнинги" - это полноценные ошибки компиляции с точки зрения языка С.

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

Re: Нескольно простых вопросов о программировании AVR на Си.

Пт мар 27, 2020 20:58:15

Хотелось бы пруфов на авторитетов о том, что Си - язык со строгой типизацией.

Re: Нескольно простых вопросов о программировании AVR на Си.

Пт мар 27, 2020 22:42:58

Хотелось бы пруфов на авторитетов о том, что Си - язык со строгой типизацией.


Ну в первую очередь надо спросить у вас, что вы имели в виду под "нестрогой типизацией" в конкретном случае. Вы ведь вели речь о "ворнингах", то есть имели в виду конкретные ситуации в коде, а не какой-то огульный холивор.

Приводите примеры. А далее - стандарт языка С. Авторитетнее некуда.

Re: Нескольно простых вопросов о программировании AVR на Си.

Пт мар 27, 2020 22:52:30

Сравните синтаксис Паскаля и Си, и вы уразумеете, что значит строгая типизация. В паскале целочисленной переменной вы не присвоите значение действительной переменной, например. В Си - легко, и даже варнинга не будет.
В общем, рекомендую. А, говорят, Ада ещё и паскалю 100 очков даст.
Си - это просто вакханалия, один char чего стоит...

Re: Нескольно простых вопросов о программировании AVR на Си.

Сб мар 28, 2020 01:11:06

Сравните синтаксис Паскаля и Си, и вы уразумеете, что значит строгая типизация. В паскале целочисленной переменной вы не присвоите значение действительной переменной, например. В Си - легко, и даже варнинга не будет.


Если вы имели в виду возможность неявного преобразования плавающих типов к целым в С, то да - в этом отношении язык С нестрого типизирован.

Re: Нескольно простых вопросов о программировании AVR на Си.

Сб мар 28, 2020 07:47:27

Не в ЭТОМ смысле, а ВООБЩЕ.

Добавлено after 3 minutes 4 seconds:
Можете и boolean попробовать, и операции над целыми числами... Паскаль не позволит скомпилировать код, где применяются "несовместимые" типы, Си позволит. Это и есть нестрогая типизация.
А варнинг не ошибка, а костыль, вытекающий из "нюансиков" Си.

Re: Нескольно простых вопросов о программировании AVR на Си.

Сб мар 28, 2020 18:16:27

Можете и boolean попробовать, и операции над целыми числами... Паскаль не позволит скомпилировать код, где применяются "несовместимые" типы, Си позволит. Это и есть нестрогая типизация.


Нет, это лишь частные вольные предположения о том, что является "строгой типизацией", а что является "нестрогой типизацией". Банальный интернетный холивор для пионэров. Неинтересно.

А варнинг не ошибка, а костыль, вытекающий из "нюансиков" Си.


Никаких "нюансиков Си" тут нет. Это действительно "костыли", но "костыли" вытекающие лишь из пожеланий и девичьих мечт разработчиков конкретного компилятора. Никакого отношения к самому языку С эти "костыли" не имеют даже отдаленно.

В языке С нет никаких "варнингов" и нет никаких "ошибок" в принципе. А есть только диагностические сообщения, выдаваемые в ситуациях, когда их требует стандарт языка. В языке С все такие диагностические сообщения равны между собой. А что там написал в сообщении ваш компилятор (слово "варнинг" или слово "ошибка") - это целиком и полностью студенческая самодеятельность вашего компилятора. Я уже ясно объяснил выше, откуда у этой самодеятельности ноги растут.

Знать особенности вашего компилятора (т.е. распознавать ситуации, когда он рапортует формальные "ошибки" как "варнинги") - это ваша обязанность. Некоторые компиляторы могут помочь вам в этом (напр. ключ `-pedantic-errors` в GCC и Clang), а с некоторыми вам придется опираться исключительно на собственные знания. Язык С, как таковой, здесь ни в чем не виноват.

Re: Нескольно простых вопросов о программировании AVR на Си.

Сб мар 28, 2020 18:55:52

Не пойму я вашего флейма. Ссылки на авторитетные источники о том, что Си есть язык строгой типизации, вы не привели, кормите какими-то баснями...

Добавлено after 2 minutes 22 seconds:
Почитайте ликбез: https://m.habr.com/ru/post/161205/

Re: Нескольно простых вопросов о программировании AVR на Си.

Сб мар 28, 2020 19:51:19

Не пойму я вашего флейма.


Это потому, что флейм тут исключительно ваш. Вы то прыгаете в надъязыковые теоретические классификации, то разглагольствуете про какие-то конкретные компиляторные "варнинги". Это совершенно разные, никак не связанные темы. Добиться от от вас конкретного объяснения, о чем же вы ведете речь, мне пока не удалось. Пока вы не определитесь с тем, что сказать-то хотели, ваши разглагольствования будут восприниматься как флейм.

Ссылки на авторитетные источники о том, что Си есть язык строгой типизации, вы не привели,


Не нужно уж совсем вот так нагло врать. Я же ясно сказал: источником является спецификация языка. Авторитетнее некуда.

кормите какими-то баснями...


Мои басни - ни что иное как точное, четкое и авторитетное описание свойств языка, который является темой данной ветки. "Ликбез", как вы его назвали.

В предыдущем сообщении речь о каких-то "костылях", "варнингах" и т.п. В ответ на проведенный мной ликбез по этой теме вы вывалили сюда ссылку на какую-то статью, которая к этой теме вообще никаким боком не относятся. "Флейм", как вы его назвали.

Возникает очевидный вопрос: вы точно не перепутали "ликбез" с "флеймом"? ))

(Что касается статьи по ссылке в самостоятельном рассмотрении: это не "ликбез", а предложенный автором доморощенный вариант классификации. Вполне стройный и логичный, малость устаревший. Не хуже, не лучше других. Авторов этих, каждый со своим вариантом - хоть залейся. Как я уже сказал, мне эти теоретические холиворы не интересны.)

Re: Нескольно простых вопросов о программировании AVR на Си.

Сб мар 28, 2020 20:01:06

Так процитируйте спецификацию Си! То место, где говорится о типизации и её строгости (или сильности). Хватит уже собственных интерпретаций! Можете Кернигана процитировать, тоже сойдёт за авторитет.
Ответить