Перейти к содержанию
    

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

union {
	uint8_t AlarmStatus;
	struct {
		uint8_t MarkFault	: 1;
		uint8_t LineFault 	: 1;
		uint8_t SensFault	: 1;
		uint8_t SensFire	: 1;
		uint8_t dummy		: 4;
	} sAlarmStatus;
};

А надо описывать битовыми масками.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Без __attribute__ ((__packed__))  или  #pragma pack(push,1) могут быть проблемы. Здесь это рассматривалось: https://habr.com/ru/post/142662/

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Внутри struct биты будут расположены вплотную, как описано и в указанном порядке, но без #pragma попытка прямого обращения к байту, где хранятся этим поля, действительно непредсказуемо. Если проц 32-х битный, то без нужной прагмы будет создано 32-битное слово для этих 8ми бит.

 

Достаточно обрамить ваш код такой конструкцией (GCC) и весь union станет строго 8-битным:

#pragma pack(push, 1) 

.....

#pragma pack(pop)

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

4 минуты назад, Forger сказал:

биты будут расположены вплотную, как описано

Но с какого конца - младшего бита или старшего, не гарантируется, правильно?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

5 minutes ago, ViKo said:

Но с какого конца - младшего бита или старшего, не гарантируется, правильно?

Расположение битов внутри как раз регламентировано: сверху младшие, внизу старшие (для little endian). Тут переживать не стоит.

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

Поэтому я добавляют в таких случаях assert (sizeof(...) == ...). Так хотя бы компилятор заругается, если что.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

6 минут назад, Forger сказал:

Расположение битов внутри как раз регламентировано: сверху младшие, внизу старшие (для little endian). Тут переживать не стоит.

Вот насчет этого я не уверен.

 

6 минут назад, Forger сказал:

развалится структура пакета

Так, эти прагмы вышепоказанные решают же.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

3 minutes ago, ViKo said:

Вот насчет этого я не уверен.

В противном случае применение битовых полей вообще было бы невозможно. 

Я активно применяю битовые поля, проблем не было, кроме выравнивания, когда забывал в нужных местах добавить прагму.

 

Quote

Так, эти прагмы вышепоказанные решают же.

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

19 минут назад, Forger сказал:

В противном случае применение битовых полей вообще было бы невозможно. 

Возможно. Там где позиция бита не влияет. Куда записал, оттуда и прочитал. А если это аппаратный бит, или структура передаётся наружу, то гарантии нет.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 minute ago, ViKo said:

А если это аппаратный бит, или структура передаётся наружу, то гарантии нет.

Положение бита внутри структуры будет неизменно. Внутри структуры.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 час назад, Forger сказал:

...но без #pragma попытка прямого обращения к байту, где хранятся этим поля, действительно непредсказуемо.

Почему? Что здесь не предсказуемо будет? Если не пытаться лезть через указатели в память, то в AlarmStatus как раз таки будут лежать эти битовые поля.

Цитата

Расположение битов внутри как раз регламентировано: сверху младшие, внизу старшие (для little endian). Тут переживать не стоит.

Порядок битов (от младшего к старшему в порядке описания или наоборот) определяется реализацией (п. 6.7.2.1 пп. 10).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 час назад, Arlleex сказал:

(п. 6.7.2.1 пп. 10)

И где его добыть?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

И на C++ стандарт доступен?
Раньше, вроде, бесплатно не давали.

В общем, даром стандарты недоступны. Черновики можно найти.
https://ru.stackoverflow.com/questions/417797/Где-взять-стандарт-c

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 hour ago, Arlleex said:

Почему? Что здесь не предсказуемо будет? Если не пытаться лезть через указатели в память, то в AlarmStatus как раз таки будут лежать эти битовые поля.

Написал же выше:

3 hours ago, Forger said:

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

....

Если нет - то не обязательно.

 

Я сам очень активно использую битовые поля внутри проекта, многие без передачи наружу. Очень помогает в читаемости кода.

На порядок удобнее, чем маски. А если использовать с union, то вообще сказка!

Компилятор хорошо понимает их и делает все правильно, не хуче, чем маски

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

48 минут назад, ViKo сказал:

И где его добыть?

http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

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

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...