※ 引述《galic (嘎利)》之铭言:
: ※ 引述《ando5566》之铭言:
: : 各位版友日安,
: : 最近小弟要将32bits平台的CAN protocol API, porting 至8bits平台上,
: : 遇到了一个问题, 如下:
: ...
: : 但是因为我的原意是porting, 所以我不希望影响任何其他写法,
: ^^^^^^^
: : 尝试过使用union的作法, 但是仍会面临无法使EID寻址在第12bit的问题。
: : 想请教版上高手, 有其他方法吗?
: : 谢谢!
: 我不知道这篇为什么没有人回正解...
: 在我唸书的时候
: 记得老师曾经说过“C 的 bit-fields 不要乱用”
: 尤其是在涉及 memory format (layout) 相关操作的时候
: 像是 network package 的格式、操作 CPU registers …
: 一开始觉得没什么
: 但后来真的有看过用 C 开发的 http APIs 竟然用 bit-fields 来 mapping 封包
: 也看过 Arduino 的教学文件竟然是用 bit-fields 在操作 LED 灯和 GPIO
: 所以我觉得推文只要一句“bit-fields 不要乱用”
: 应该就足够了
: 不然,
: 问 google 也会给你答案
: `c bit fields portability' 或 `bit fields portability'
: 有趣的是,差一个 C 搜出来的会是不同答案
: 不过观点是一致的
: 总之,你需要的是透过 bit manipulation 来操作
: (有时候打包成 macro 会直接叫 bitmask, bitset 或 bitops....)
: ref: https://stackoverflow.com/a/263738
先讲结论...
1. bit-field 真的满难用的
2. 原Po的问题,以C standard来看,我是找不到可以只改declaration不改其他code完成
porting的方法....
====
以下来自于C11 standard关于bit-field的章节
Section 6.7.2.1 paragraph 5 提到,Bit-field只能用在_Bool, signed int,
unsinged int以及其他implementation defined的型态上。先撇开_Bool不谈,
signed int以及unsigned int 在 section 5.2.4.2.1 中提到必须至少是16-bit。
因此原po提到bit-field width 11 编译不过,很可能是这compiler根本不合standard
不过8-bit compiler这种事也很常见,希望他有在说明书中写清楚就是了
再来是Section 6.7.2.1 paragraph 11提到,implementation可以自由选择allocate任意
addressable storage unit来装bit-field,只要足够大就可以了,后面虽然有加一个补
充说如果还有空间,紧邻的下一个bit-field应该被放到同一个storage unit,但最后又
补一句说,同一个unit里假如放了多个bit-field,它们的顺序,是implementation
defined
简单来说,假如我们定了一个总长32bit的一组bit-fields,分别是5bit, 9bit, 14bit,
4bit,首先standard并不保证这四组bit-fields会紧邻再一起塞在一个32-bit的storage
unit中,第二就算它们紧邻在一起,也不能保证他们的顺序就是5,9,14,4
bit-field在多数情况下确实是好用,只要能够确定compiler的行为,比方说透过
各种pragma去限制,用bit-field也没什么不好 ,而用bit-field会让code porting到不同
平台上的难度变高,这个也是肯定的
最后如果我是老师,面对大一资工系刚接触C code的学生们,我应该也会选择跟他们说
bit-field暂时不要用,先学好bit operation比较重要。第一个避免用bit-field踩到洞
,第二个bit operation是许多公司的面试必考题,根据我以前在某芯片厂面试的经验
bit operation非常意外地可以刷掉很多名校并且成绩不错的人。我只是希望以后减少因
为bit operation被刷掉的人,真的满可惜的。