Jump to content

    
ViKo

Битовые поля

Recommended Posts

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

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;
};

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

Share this post


Link to post
Share on other sites

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

 

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

#pragma pack(push, 1) 

.....

#pragma pack(pop)

 

Share this post


Link to post
Share on other sites
4 минуты назад, Forger сказал:

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

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

Share this post


Link to post
Share on other sites
5 minutes ago, ViKo said:

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

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

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

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

 

Share this post


Link to post
Share on other sites
6 минут назад, Forger сказал:

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

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

 

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

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

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

Share this post


Link to post
Share on other sites
3 minutes ago, ViKo said:

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

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

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

 

Quote

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

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

Share this post


Link to post
Share on other sites
19 минут назад, Forger сказал:

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

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

Share this post


Link to post
Share on other sites
1 minute ago, ViKo said:

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

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

Share this post


Link to post
Share on other sites
1 час назад, Forger сказал:

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

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

Цитата

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

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

Share this post


Link to post
Share on other sites

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

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

Share this post


Link to post
Share on other sites
1 hour ago, Arlleex said:

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

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

3 hours ago, Forger said:

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

....

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

 

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

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

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

 

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.