-
- Возвращать ее из функции.Все остальное мудозвонство в чистом виде. - PlainUser(08.05.2020 18:51)
- Да чего морочить друг другу головы, все элементарно: il-2(146 знак., 08.05.2020 15:49 - 17:57)
- Код в ассемблере далек от оптимального, в исходниках PREPARE_X_READ
ничем не лучше. - fk0(08.05.2020 16:16)
- PREPARE_X_READ - это только альтернатива условной директиве в
хедере. Можно и без него. Да и остальное тоже - как еще один
вариант. Лично я - за инкапсуляцию. - il-2(08.05.2020 16:33)
- Ты x_ptr сделал глобальным, в итоге он не оптимизируется. Если его
сделать статическим и присваивать в хидере -- по крайней мере
оптимизируется и косвенной адресации мы в коде не увидим. И
во-вторых у тебя никто не мешает написать x=!0. И в третьих
проблемы с const на гарвардских архитектурах. В четвертых макрос
сулящий проблемы: я вариант с геттером инлайн-функцией (их умел
даже hitech-C, если кто-то сегодня не умеет, то наверное следует
сменить компилятор) предлагал ниже. - fk0(08.05.2020 16:43)
- Поправил свой пример выше - написал "static int x;" Так секретнее :-) И кстати - указатель на const является
указателем на данные с модификатором "только чтение". Даже в
гарвардовской архитектуре - он не меняет область данных, для этого
надо использовать нестандартные ключевые слова - например как int
__flash *ptr; в IAR-AVR. По моему так... - il-2(08.05.2020 18:05)
- Так всегда обращение через указатель, медленно. Я предлагал указатель сделать static const -- тогда оптимизатор всегда твердо уверен в его значении и может выкинуть (обращаться напрямую к x). Гарвардовская архитектура по-разному сделана у разных компиляторов. У пиков -- по адресу понимает (hitech-c, в рантайме выбирает один из двух вариантов обращения по-указателю) если указатель (если переменная -- сразу знает адрес и генерит нужный код), у KEIL C51 нельзя было мешать const fk0(277 знак., 08.05.2020 19:57)
- Ну то что ты предлагаешь здесь и там уже не соответствует хотелкам
топикстартера. Он конечно хочет странного, но твой вариант к этой
странности не подходит, ибо ты в хедере сразу открываешь полный
доступ к этой "немодифицируемой извне" переменной, а затем зачем-то
предлагаешь какие-то геттеры/сеттеры/статические указатели для
работы с ней. Нафиг они тогда не нужны, можно напрямую в переменную
фигачить. В общем - странные желания порождают странные решения :-) - il-2(08.05.2020 17:45)
- Я имя изменил на _x, т.е. x=!0 не написать. Тут дилемма: с одной стороны хочется скрыть, но с другой, эффективное обращение к переменной (преимущественно чтение) возможно только при прямом знании адреса. Я говорю преимущественно про 8-битные архитектуры, где чтение по-указателю -- тяжелое. Для ARM'ов пофигу (тем более часто там вследствии особенностей будет так или иначе по-указателю: у ARM сложная загрузка адреса, у MIPS выкрутасы в релокацией и позиционно-независимым fk0(41 знак., 08.05.2020 20:03)
- Поправил свой пример выше - написал "static int x;" Так секретнее :-) И кстати - указатель на const является
указателем на данные с модификатором "только чтение". Даже в
гарвардовской архитектуре - он не меняет область данных, для этого
надо использовать нестандартные ключевые слова - например как int
__flash *ptr; в IAR-AVR. По моему так... - il-2(08.05.2020 18:05)
- Ты x_ptr сделал глобальным, в итоге он не оптимизируется. Если его
сделать статическим и присваивать в хидере -- по крайней мере
оптимизируется и косвенной адресации мы в коде не увидим. И
во-вторых у тебя никто не мешает написать x=!0. И в третьих
проблемы с const на гарвардских архитектурах. В четвертых макрос
сулящий проблемы: я вариант с геттером инлайн-функцией (их умел
даже hitech-C, если кто-то сегодня не умеет, то наверное следует
сменить компилятор) предлагал ниже. - fk0(08.05.2020 16:43)
- PREPARE_X_READ - это только альтернатива условной директиве в
хедере. Можно и без него. Да и остальное тоже - как еще один
вариант. Лично я - за инкапсуляцию. - il-2(08.05.2020 16:33)
- Код в ассемблере далек от оптимального, в исходниках PREPARE_X_READ
ничем не лучше. - fk0(08.05.2020 16:16)
- Если определеить задачу иначе, то "глобальная переменная" =>
read only access откуда угодно, каким угодно кодом/инструкциями. Но
изменение/modify => это строго один код/инструкция (не другие
инструкции). Зачем? "Сложность найти по файлам проекта где это
делается". Отсюда - классическая задача инкапсуляции доступа. Для C
решается так: Перейти от работы с переменной к accessor-методам
get/set. Переменную саму по себе скрыть (инкапсулировать), убрав
запись о ней из RxTx(2000 знак., 08.05.2020 00:36)
- Теперь я допишу то, что я по некоторым причинам не дописал вчера. На первый взгляд нам не удалось решить вопрос с уникальностью мест модификации/вызова. Как я заметил по обсуждениям выше есть желание сделать это место уникальным хотя бы на уровне линковки. Я хочу показать, что здесь неверен сам подход по обретению такого контроля. Что мы имеем исходя из исходных условий? Мы имеем некий spaghetti (или просто неструктурированный) код, который не контролируем до такой RxTx(1728 знак., 08.05.2020 10:24)
- В отдельном модуле (.c) определить переменную как, например, int x.
В хидерах определить как extern const int x. Переменная будет
читаема, но не записываема. Для изменения переменной в том же
отдельном модуле, где определена переменная, сделать специальную
функцию и разместить её декларацию в хидерах. Преимущество перед
твоим методом: доступ на чтение более легковесный (чтение ячейки
памяти, вместо вызова функции). Работает только в C, или нужно
добавлять extern "C" fk0(49 знак., 08.05.2020 01:20)
- только в хидере еще в #ifdef обернуть желательно. Типо такого: LightElf(86 знак., 08.05.2020 10:21)
- GCC: error: conflicting type qualifiers for 'x' - NAUT(08.05.2020 09:30)
- +1, безусловно это решение более легковесное. У каждого решения есть свои плюсы и минусы. - RxTx(08.05.2020 09:18)
- Меня терзают смутные сомнения... il-2(760 знак., 08.05.2020 08:09)
- А ты не включай, или сделай #ifdef как LightElf выше показал. А то ошибка действительно будет. В гарвардской архитектуре (где код нужно генерировать другой) такое может не заработать. А может и заработать. Hitech-C для PIC18 в рантайме по адресу определял как к переменной обращаться (не в compile time). Только обращаться нужно было бы через указатель. А линкер не ругнется: в C (в отличие от C++) тип в имя не кодируется и линкеру ничего о типе не известно. - fk0(08.05.2020 11:56)
- Но вообще сделали бы уже MPU или просто дебаговое прерывание на переменную и били бы по рукам другие процессы при обращении lloyd(51 знак., 07.05.2020 21:32)
- Как функцию, возвращающую значение. - Cкpипaч(07.05.2020 21:08)
- но тогда как проконтролировать вызов функции... можно конечно
объявить функцию локально, но где тогда смысл? Данная задача должна
решатся функциями компилятора-линкера, Для переменных помеченная
определенным модификатором, компилятор в объектнике выставляет
счетчик модификаций, и линкер, просмотрев все модули, выкидывает
предупреждение - IBAH(07.05.2020 22:36)
- Язык Си старше меня, например, и он уже давно никому ничего не должен. А так можно сделать отдельный сишный модуль оч. маленького размера, в котором эта переменная (объявленная static) будет меняться, внимательному контролю подлежит только он. Остальной код читает её через функцию get. - SciFi(08.05.2020 10:22)
- Встречал как-то кулхацкерский вариант с неполным объявлением типа и жонглированием typedef. Исходная идея была другая - изолированно компилировать модули. Оно рушилось при включении полного объявления перед неполным, но это обходилось ручками. В результате применения вылезли бока - типы (структуры) в разных модулях со временем разъехались чуток (где-то чего-то добавили, Vit(811 знак., 08.05.2020 02:03)
- иногда прототип функции безо всяких хедеров прям в текст перед вызовом вставляю... - Vit(07.05.2020 21:57)
- но тогда как проконтролировать вызов функции... можно конечно
объявить функцию локально, но где тогда смысл? Данная задача должна
решатся функциями компилятора-линкера, Для переменных помеченная
определенным модификатором, компилятор в объектнике выставляет
счетчик модификаций, и линкер, просмотрев все модули, выкидывает
предупреждение - IBAH(07.05.2020 22:36)
- а зачем? - LordN(07.05.2020 20:58)
- Чтобы не было соблазна... Например
PizdecVsemu=!0; Ищи потом по файлам проекта какой объект запустил этот процесс - IBAH(07.05.2020 22:22)
- Для этого нужно писать на C++. Сеттеры-геттеры там могут быть во-первых легковесными, во-вторых синтаксически выглядеть как переменная. Впрочем, легковесный сеттер-геттер можно сделать и в голом C: - fk0(08.05.2020 12:06, ссылка)
- И что, поиск сломался? Если кодят враги, от них так не убережёшься, нужно приставить комиссара с наганом. А удобство поиска по тексту делается на раз. Хоть макросами, хоть функциями, хоть как угодно. - SciFi(08.05.2020 09:03)
- Чтобы не было соблазна... Например
PizdecVsemu=!0; Ищи потом по файлам проекта какой объект запустил этот процесс - IBAH(07.05.2020 22:22)